CellForItemAtIndexPath của UICollectionView không được gọi


104

Chỉ có lần thứ hai tôi sử dụng UICollectionView và có lẽ tôi đã cắn nhiều hơn những gì tôi có thể nhai nhưng tuy nhiên:

Tôi đang triển khai UICollectionView (myCollectionView) sử dụng UICollectionViewCell tùy chỉnh mà tôi đã phân lớp. Các ô phân lớp (FullReceiptCell) chứa UITableView và là kích thước của bộ điều khiển chế độ xem. Tôi đang cố gắng cho phép cuộn ngang giữa các FullReceiptCell.

UICollectionViewController phân lớp có chứa myCollectionView đang được đẩy vào ngăn xếp điều khiển điều hướng. Hiện tại, các loas myCollectionView và cuộn ngang được bật. Tuy nhiên, không có ô nào được nhìn thấy. Tôi đã xác nhận rằng

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

đã chạy và đang trả về một số nguyên lớn hơn 0. Tôi cũng đã xác nhận rằng đại biểu và nguồn dữ liệu của myCollectionView đã được đặt đúng cách trong IB cho UICollectionViewController phân lớp.

Phương pháp nơi các ô sẽ được tải:

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

không được gọi.

Đây là nơi tôi đẩy UICollectionViewController và phương thức viewDidLoad của tôi trong bộ điều khiển đó (LƯU Ý: initWithBill là ghi đè của trình khởi tạo bình thường):

Trong tệp .m ViewControllers trước đây:

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

Trong 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];

Bất kỳ manh mối tại sao nó không được gọi?


Tôi đang sử dụng XIB. Tôi không thể dequeue bất cứ thứ gì trong cellForItemsAtIndexPath vì nó không bao giờ được gọi.
IkegawaTaro

Câu trả lời:


135

Đối với những người vấp ngã ở đây sau này .... lý do:

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

không được gọi là do kích thước itemSize cho chiều cao của collectionViewFlowLayout quá lớn.

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

Nếu tôi thay đổi chiều cao thành 410, nó sẽ thực thi cellForItemAtIndexPath.


Bạn có thể nói rõ hơn một chút. Cùng đang xảy ra đối với tôi
user1010819

Tôi chỉ phát hiện ra rằng bạn cần phải cẩn thận với collectionViewContentSize, quá
Dimitar Marinov

49
Trong trường hợp bạn đang sử dụng autolayout - hãy nhớ đặt giới hạn chiều cao trên collectionView - lãng phí nhiều giờ cho việc này!
bpn

cho chiều cao kỷ lục Constrain không làm việc cho tôi .. ép horizontal center đã làm các trick
Mohamed Emad Hegab

4
Nếu collectionView của bạn bị giới hạn ở topLayoutGuide với AutoLayout và không được phép cuộn dưới NavigationBar, hãy đảm bảo bỏ chọn Adjust Scroll View InsetsViewController trên Storyboard.
Bruno Galinari

96

Trong trường hợp của tôi, đó là do lớp bố cục của tôi đã phân lớp không chính xác từ UICollectionViewLayoutthay vìUICollectionViewFlowLayout


1
CẢM ƠN BẠN. Làm phiền tôi, tôi đã dành nhiều thời gian cho điều đó.
Rambatino

Đây cũng là vấn đề của tôi! Nó hơi phản trực giác, vì vậy nó thậm chí không xảy ra với tôi. Cảm ơn vì điều đó!
WendiKidd

Tương tự cho tôi! Thật dễ dàng để bỏ qua điều đó! cảm ơn một lần nữa
arvidurs

Facepalm đây, cảm ơn bạn đã chỉ ra điều này (4 năm trước).
Milander

Tôi đã phải đối mặt với cùng một vấn đề. Cảm ơn
Piyush Gupta

31

CellForItemAtIndexPath sẽ không được gọi nếu bạn không cung cấp thông tin kích thước nội dung cho dạng xem bộ sưu tập.

  1. Nếu bạn đang sử dụng bố cục Luồng : Bạn cần đặt kích thước mục hợp lý.
  2. Nếu bạn có một bố cục tùy chỉnh được phân lớp từ UICollectionViewLayout : Đảm bảo rằng bạn đang trả về kích thước thích hợp từ phương thức collectionViewContentSize.

Trong trường hợp thứ hai, bạn cũng sẽ thấy rằng layoutAttributesForElementsRect của bạn cũng không được gọi. Nguyên nhân là do bạn chưa xác định kích thước nội dung của mình là bao nhiêu và mặc định kích thước sẽ là CGSizeZero. Điều này về cơ bản cho chế độ xem bộ sưu tập biết rằng bạn không có bất kỳ nội dung nào để vẽ nên nó không bận tâm đến việc yêu cầu bạn cung cấp các thuộc tính hoặc ô.

Vì vậy, chỉ cần ghi đè collectionViewContentSize và cung cấp kích thước phù hợp ở đó, nó sẽ giải quyết được vấn đề của bạn.


1
Ví dụ để sử dụng kích thước đầy đủ có sẵn, trở collectionView.frame.size từ collectionViewContentSize (không chỉ đơn giản collectionView.contentSize mặc định là 0, 0)
Adam Loving

Cảm ơn! Câu trả lời này đã giúp tôi b / c Tôi có một UICollectionViewLayout tùy chỉnh. Nếu tôi khởi động ứng dụng trong trình mô phỏng theo hướng ngang, một số ô sẽ không xuất hiện trong chế độ xem ban đầu. Ghi đè kích thước nội dung đã khắc phục sự cố này cho tôi.
Chris Livdahl

1
Cảm ơn bạn. Trong trường hợp của tôi, số collectionViewContentSize0 được trả về không chính xác cho chiều rộng, đó là lý do tại sao giá trị cellForItemAtIndexPathkhông được gọi.
izerik

16

Có thể tôi chỉ nhìn qua nó, nhưng có vẻ như bạn thiếu người đại diện và nguồn dữ liệu của bạn. Trong tệp tiêu đề của bạn, hãy đảm bảo rằng bạn đã thêm những thứ sau:

<UICollectionViewDelegate, UICollectionViewDataSource>

và trong phương thức viewDidLoad của bạn, hãy thêm cái này:

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

Ngoài ra, nếu bạn đang tải nó qua .xib, hãy đảm bảo rằng bạn đã kết nối IBOutlet với UICollectionView.


1
Tôi không hiển thị nó nhưng tôi đã có người đại diện và nguồn dữ liệu được ghi chú trong tệp tiêu đề. Ngoài ra, tôi đã kết nối IBOutlet với myCollectionView. Người ủy quyền và nguồn dữ liệu cho lần xem tuyển tập này đã được đặt thành FullReceiptViewController. Điều kỳ lạ là numberOfItemsInSection (một phương thức giao thức nguồn dữ liệu) đang được gọi và trả về một số nguyên lớn hơn 0.
IkegawaTaro

Hmm, Khi bạn khởi chạy ứng dụng, chế độ xem Bộ sưu tập có hiển thị hay làm gì không? Nghe có vẻ như nó có một số mặt hàng trong đó nếu numberOfItemsInSection trả về một cái gì đó lớn hơn 0.
Anthony Castelli

Cảm ơn đã theo dõi. Bộ sưu tập hiển thị ... Tôi có thể biết vì tôi đã thay đổi màu nền. Tôi tin rằng tôi đã tìm ra vấn đề: [self.myCollectionViewFlowLayout setItemSize: CGSizeMake (320, 548)]; Điều này quá lớn. Nếu tôi giảm chiều cao xuống 410, tôi có thể gọi phương thức cellForItemAtIndexPath.
IkegawaTaro

@AnthonyCastelli Xin chào, tôi cũng đang đối mặt với vấn đề tương tự, numberOfItemsInSection được gọi trên cửa sổ bật đến viewController nhưng không phải cellForItemsAtIndexPath. vậy bạn có nắm được manh mối không?
Bhavin Kansagara

16

Để biết phân cấp chế độ xem phức tạp hơn, vui lòng kiểm tra blog này . Nó đã cứu mạng tôi!

self.automaticallyAdjustsScrollViewInsets = NO;

1
Tôi đã dành rất nhiều thời gian cho việc này - và tất cả đã kết thúc. Nếu sử dụng bảng phân cảnh hoặc XIB, hãy xem bộ điều khiển chế độ xem chính và bỏ chọn "Điều chỉnh các nội dung trong chế độ xem cuộn" trong Trình kiểm tra thuộc tính được bật theo mặc định. Tôi đã thử tất cả các câu trả lời khác và chúng không hoạt động, nó dẫn đến điều này.
etayluz

15

Nếu lớp của bạn là lớp con từ UICollectionviewController và bạn đang tạo collectionView theo lập trình thì hãy sử dụng

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

    collectionView?.setCollectionViewLayout(layout, animated: false)

Đây là câu trả lời đã giải quyết vấn đề của tôi! Phương thức ghi đè func collectionView (_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {<# code #>} không hoạt động với tôi.
Mike

8

Tôi đang sử dụng autolayout và trong trường hợp của tôi, giới hạn chiều cao bị thiếu


6

Vấn đề của tôi là tôi có 2 chế độ xem bộ sưu tập trong cùng một chế độ xem và cả hai đều đang chia sẻ một UICollectionViewFlowLayoutphiên bản được tính toán . Sau khi tôi tạo các phiên bản riêng biệt của cùng một bố cục luồng, nó hoạt động tốt.


5

Trong trường hợp của tôi, điều tôi đã rất ngớ ngẩn quên làm là triển khai UICollectionViewDataSourcephương thức giao thức numberOfItemsInSection, vì vậy đó là một điều khác cần kiểm tra.


4

Ngoài ra, hãy đảm bảo rằng reloadData không được gọi trong khi chế độ xem bộ sưu tập đang cập nhật với hoạt ảnh (chèn, xóa, cập nhật hoặc performanceBatchUpdates).


4

Trong trường hợp của tôi, thiết lập đã collectionView.prefetchingEnabled = NO;giải quyết được vấn đề của tôi. Chỉ hoạt động trên iOS 10.


2
Tôi đã ủng hộ câu trả lời đó một thời gian trước và hôm nay nó đã giúp tôi một lần nữa: D Bạn xứng đáng là một Cao quý cho người đàn ông trả lời này. Cảm ơn một lần nữa!
Maciek Czarnik

câu trả lời này đã làm việc cho tôi! Tôi ước có một lời giải thích tại sao lại bao gồm nó bởi vì tôi chưa bao giờ đặt nó thành true từ đầu.
Lance Samaria

3

Điều đó đã xảy ra với tôi khi chiều cao mục == 0 bằng cách sửa phương thức cellForItem đó được gọi.


3

Mười phút trước tôi cũng gặp phải vấn đề này, tôi đã mắc một sai lầm ngớ ngẩn.

Ý định của tôi là sử dụng UICollectionViewFlowLayout,

Nhưng vì sai lầm, tôi đã sử dụng UICollectionViewLayout.


3

Trong trường hợp của tôi, việc thay đổi độ mờ của UINavigationBar thành KHÔNG đã giải quyết được vấn đề.


3

Trong Xcode 7.0.1, chúng tôi gặp sự cố này khi sao chép bảng phân cảnh và mã đi kèm từ một dự án khác. Chế độ xem bộ sưu tập có bố cục luồng tùy chỉnh được đặt trong bảng phân cảnh. Giải pháp là:

  • Loại bỏ bố cục luồng trong IB
  • Biên dịch / chạy ứng dụng
  • Đặt lại bố cục luồng

Bây giờ nó đã hoạt động :)


2

Đảm bảo numberOfSectionsInCollectionViewtrả về một số nguyên dương.

Phải có ít nhất một phần trong bộ sưu tập.


2

Đảm bảo - (NSInteger) collectionView: numberOfItemsInSection: đang trả về một giá trị dương (đọc, lớn hơn 0). Có thể là vấn đề đặt [self.collectionView reloadData]; trong trình xử lý hoàn thành.


2

Tôi quên đặt mặt nạ tự động khôi phục thành false trên chế độ xem bộ sưu tập:

collectionView.translatesAutoresizingMaskIntoConstraints = false

2

Nó có thể là những vấn đề về bố cục được thực hiện. Kiểm tra cảnh báo bố cục từ bảng điều khiển, nếu tồn tại.


2

Trong trường hợp của tôi, chế độ xem bộ sưu tập không hiển thị đầy đủ trong chế độ xem gốc do các ràng buộc bố cục tự động sai. Vì vậy, việc sửa các ràng buộc đã làm cho chế độ xem bộ sưu tập hiển thị tất cả và cellForItemAtIndexPath được gọi.


2

Trong bảng phân cảnh / xib thuộc tính UICollectionView ô Kích thước KHÔNG PHẢI là {0, 0}


2

Nếu bạn đang sử dụng giao thức chế độ xem bộ sưu tập, bạn phải kết nối giao thức CollectionViewDataSourceCollectionViewDelegatevới ViewController của bạn. Cửa hàng trình tạo giao diện


1

Tôi cũng vậy. Tôi đã có 2 UICollectionView và tôi đã xóa một lần vì tôi không cần nó. Sau đó, tôi nhận ra rằng CellForItemAtIndexPath không được gọi mà là các phương thức bắt buộc khác. Tôi đã thử tất cả những điều trên nhưng sau đó tôi đã thực hiện phép thuật tiêu chuẩn. Đã xóa chế độ xem bộ sưu tập khỏi bảng phân cảnh và thêm lại. Sau đó, nó bắt đầu hoạt động. Không chắc tại sao và tôi không có lời giải thích nhưng có thể một số vấn đề kết nối.


Tôi đã sao chép UICollectionView của mình từ một UIViewController khác trong bảng phân cảnh. Tôi đã xóa CollectionView và thêm lại để làm cho nó hoạt động. Cảm ơn bạn vì câu trả lời.
Drunken Daddy,

1

Chỉ cần giải quyết vấn đề này, cho một tình huống cụ thể.

Trong trường hợp của tôi, tôi đang khởi tạo thủ công UICollectionViewController trong ViewController mẹ, sau đó thêm chế độ xem của UICollectionViewController làm chế độ xem phụ.

Tôi đã giải quyết vấn đề bằng cách gọi 'setNeedsLayout' và / hoặc 'setNeedsDisplay' trên collectionView trong viewDidAppear của cha mẹ:

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

1

Khi sử dụng, UICollectionViewDelegateFlowLayouthãy cẩn thận với những gì hàm này trả về. Cả hai widthheightphải lớn hơn 0. Tôi đã sử dụng windowlàm tham chiếu khung nhưng do cửa sổ phân cấp chế độ xem phức tạp đã nilở trong thời gian chạy. Nếu bạn cần điều chỉnh chiều rộng của phần tử dựa trên việc sử dụng chiều rộng màn hình UIScreen.main.bounds.

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

1

Trong trường hợp của tôi, tôi đã có collectionViewtrong một UIStackViewvới alignment = .center. Vì vậy, collectionViewkhông có chiều rộng. Khi đặt stackView.alignmentthành .fillmọi thứ đều ổn.


0

Đối với tôi, tôi cập nhật chiều cao của self.view (superview của collectionView) thông qua autolayout và PHẢI gọi layoutIfNeededsau đó.

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

0

Trong trường hợp của tôi, tôi phải điều chỉnh kích thước Nội dung ước tính. kích thước nội dung đã không làm điều đó.

  let layout = collectionVC.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = CGSize(width: 100, height: 100)
    layout.estimatedItemSize = CGSize(width: 100, height: 100)

0

Tôi đã gặp một vấn đề tương tự. Nhưng thay vào đó cellForItemAtIndexPathđược gọi khi số lượng mục> 1, nhưng không được gọi khi chỉ có một mục duy nhất. Tôi đã thử nhiều giải pháp được đề xuất ở đây và tương tự với nhiều giải pháp, tôi thấy rằng nó liên quan đến định cỡ mặt hàng. Đối với tôi, giải pháp là thay đổi kích thước ước tính của UICollectionViewtừ Tự động sang Tùy chỉnh .

Đặt kích thước ước tính thành Tùy chỉnh


-1

Tôi đã mất một chút thời gian với vấn đề này khi sử dụng CollectionView trong bộ điều khiển chế độ xem chứa được tải từ bảng phân cảnh. Tôi đã kết thúc chỉ xóa bộ điều khiển chế độ xem được chứa và tạo lại nó trong bảng phân cảnh và điều này dường như giải quyết được vấn đề. Tôi đoán là có một số loại hỏng bảng phân cảnh đã xảy ra.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.