developer tip

UICollectionView의 cellForItemAtIndexPath가 호출되지 않습니다.

optionbox 2020. 8. 31. 07:40
반응형

UICollectionView의 cellForItemAtIndexPath가 호출되지 않습니다.


UICollectionView를 두 번째로 사용하고 아마도 씹을 수있는 것보다 더 많이 물었을 것입니다.

서브 클래 싱 한 사용자 지정 UICollectionViewCell을 사용하는 UICollectionView (myCollectionView)를 구현하고 있습니다. 서브 클래 싱 된 셀 (FullReceiptCell)은 UITableView를 포함하며 viewcontroller의 크기입니다. FullReceiptCells 사이의 가로 스크롤을 허용하려고합니다.

myCollectionView를 포함하는 서브 클래 싱 된 UICollectionViewController가 nav 컨트롤러 스택으로 푸시됩니다. 현재 myCollectionView loas 및 수평 스크롤이 활성화되어 있습니다. 그러나 셀은 표시되지 않습니다. 나는 확인했다

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

실행되어 0보다 큰 정수를 반환합니다. 또한 myCollectionView의 델리게이트와 데이터 소스가 IB에서 하위 클래스 UICollectionViewController로 올바르게 설정되어 있는지 확인했습니다.

셀이로드되는 방법 :

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

호출되지 않습니다.

다음은 해당 컨트롤러 내에서 UICollectionViewController 및 내 viewDidLoad 메서드를 푸시하는 위치입니다 (참고 : initWithBill은 일반 이니셜 라이저의 재정의입니다).

이전 ViewControllers .m 파일에서 :

FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];

FullReceiptViewController.m에서 :

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.myCollectionView registerClass:[FullReceiptCell class] forCellWithReuseIdentifier:@"FullReceiptCellIdentifier"];
    self.myCollectionView.pagingEnabled = YES;
    // Setup flowlayout

    self.myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
    [self.myCollectionViewFlowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    [self.myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    self.myCollectionViewFlowLayout.minimumLineSpacing = 0;
    self.myCollectionViewFlowLayout.minimumInteritemSpacing = 0;
    [self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
    //testing to see if the collection view is loading
    self.myCollectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];

왜 호출되지 않는지에 대한 단서가 있습니까?


나중에 여기에서 우연히 발견 한 사람들을 위해 .... 이유 :

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

collectionViewFlowLayout의 높이가 너무 커서 itemSize가 호출되지 않았습니다.

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];

높이를 410으로 변경하면 cellForItemAtIndexPath가 실행됩니다.


제 경우에는 레이아웃 클래스 UICollectionViewLayoutUICollectionViewFlowLayout


컬렉션 뷰에 콘텐츠 크기 정보를 제공하지 않으면 cellForItemAtIndexPath가 호출되지 않습니다.

  1. 흐름 레이아웃을 사용하는 경우 : 항목 크기를 적절하게 설정해야합니다.
  2. UICollectionViewLayout에서 서브 클래 싱 된 사용자 지정 레이아웃이있는 경우 : collectionViewContentSize 메서드에서 적절한 크기를 반환하는지 확인합니다.

In case of the latter, you will also observe that your layoutAttributesForElementsRect is also not called. The reason is that you have not specified what is your content size and by default the size will be CGSizeZero. This basically tell collection view that you don't have any content to paint so it does not bother asking you for attributes or cells.

So, just override collectionViewContentSize and provide a proper size there, it should solve your problem.


Maybe I'm just overlooking it, but it appears your missing your delegate and data source. In your header file, make sure you have added these:

<UICollectionViewDelegate, UICollectionViewDataSource>

and in your viewDidLoad method add this:

self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self;

Also, if you are loading it via an .xib, make sure you are have connected the IBOutlet to the UICollectionView.


For a more complicated view hierachy please check this blog. It saved my life!

self.automaticallyAdjustsScrollViewInsets = NO;

If your class is subclass from UICollectionviewController and you are creating collectionView programmatically then use

let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Vertical
    layout.itemSize = CGSizeMake(50, 50)

    collectionView?.setCollectionViewLayout(layout, animated: false)

I was using autolayout, and in my case height constraint was missing


In my case, what I had very stupidly forgotten to do was implement the UICollectionViewDataSource protocol method numberOfItemsInSection, so that is another thing to check.


My issue was that I had 2 collection views within the same view, and both were sharing a computed UICollectionViewFlowLayout instance. Once I created separate instances of the same flow layout, it worked fine.


It was happening for me when item height == 0 by fixing that cellForItem method was called.


Ten minutes ago I also encountered this problem, I made a silly mistake.

My intention is to use UICollectionViewFlowLayout,

But because of mistakes, I used UICollectionViewLayout.


In my case, changing UINavigationBar's translucent to NO solved the problem.


In Xcode 7.0.1, we got this problem when we copied a storyboard and accompanying code from another project. The collection view had a custom flow layout set in the storyboard. Solution was to:

  • Remove the flow layout in IB
  • Compile/run the app
  • Set the flow layout back

Now it worked :)


Make sure numberOfSectionsInCollectionView returns a positive integer as well.

There has to be at least one section in the collection.


Make sure -(NSInteger) collectionView:numberOfItemsInSection: is returning a positive (read, greater than zero) value. It may be a matter of placing [self.collectionView reloadData]; in the completion handler.


I forgot to set the autoresizing mask to false on the collection view:

collectionView.translatesAutoresizingMaskIntoConstraints = false

It can be realated layout problems. Check layout warnings from console, if exist.


In my case the collection view was not fully visible in its parent view due to wrong auto layout constraints. So fixing the constraints made the collection view all visible and cellForItemAtIndexPath was called.


In storyboard/xib UICollectionView property cellSize MUST not be {0, 0}


If you're using collection view protocols you must connect the CollectionViewDataSource and CollectionViewDelegate protocols to your ViewController. Interface builder outlets


Same happened to me. I had 2 UICollectionViews and I removed once since I didn't need that. After that I realised that the CellForItemAtIndexPath was not getting called but the other required methods. I tried all of the above but then I did the standard magic. Removed the collection view from storyboard and added again. Then it started working. Not sure why and I have no explanation but maybe some connection issues.


Also, make sure that reloadData is not called while collection view is updating with animation (insert, delete, update or performBatchUpdates).


In my case, set collectionView.prefetchingEnabled = NO; solved my problem. Only works on iOS 10.


When using UICollectionViewDelegateFlowLayout be careful on what this function returns. Both width and height should be greater than 0. I used window as frame reference but due to complicated view hierarchy window was nil at runtime. If you need adjust the width of the element based on screen width use UIScreen.main.bounds.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
           UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}

For me, I update the height of self.view (the collectionView's superview) via autolayout, and MUST call layoutIfNeeded after that.

[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];

Just resolved this issue, for a somewhat specific situation.

In my case, I was manually initializing the UICollectionViewController in a parent ViewController, and then adding the UICollectionViewController's view as a subview.

I resolved the issue by calling 'setNeedsLayout' and/or 'setNeedsDisplay' on the collectionView in the parent's viewDidAppear:

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   [_collection.view setNeedsLayout];
   [_collection.view setNeedsDisplay];
}

I sunk a bit of time with this issue coming op with a CollectionView in a Contained view controller loaded from a storyboard. I ended up just deleting the contained view controller, and recreating it in the storyboard, and this seemed to get rid of the issue. My guess is there was some kind of storyboard corruption that had taken place.


Setting collectionView frame inside custom cell's layoutSubViews() worked for me:

override func layoutSubviews() {
        super.layoutSubviews()
        let frame = self.contentView.bounds
        self.CollectionView.frame = frame
    }

참고URL : https://stackoverflow.com/questions/14668781/uicollectionviews-cellforitematindexpath-is-not-being-called

반응형