ไม่ได้เรียกเซลล์ของ UICollectionView


104

เพียงครั้งที่สองของฉันโดยใช้ UICollectionView และบางทีฉันอาจกัดมากกว่าที่ฉันสามารถเคี้ยวได้ แต่อย่างไรก็ตาม:

ฉันกำลังใช้ UICollectionView (myCollectionView) ที่ใช้ UICollectionViewCell แบบกำหนดเองที่ฉันมีคลาสย่อย เซลล์ย่อย (FullReceiptCell) ประกอบด้วย UITableView และเป็นขนาดของวิวคอนโทรลเลอร์ ฉันพยายามอนุญาตให้มีการเลื่อนแนวนอนระหว่าง FullReceiptCells

UICollectionViewController คลาสย่อยที่มี myCollectionView จะถูกพุชไปยังสแต็กคอนโทรลเลอร์ 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];

มีเงื่อนงำว่าทำไมถึงไม่ถูกเรียก?


ฉันใช้ XIB ฉันไม่สามารถจัดคิวอะไรใน cellForItemsAtIndexPath ได้เพราะมันไม่เคยถูกเรียก
IkegawaTaro

คำตอบ:


135

สำหรับผู้ที่สะดุดที่นี่ในภายหลัง .... เหตุผล:

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

ไม่ได้ถูกเรียกเนื่องจากความสูงของ itemSize สำหรับ collectionViewFlowLayout ใหญ่เกินไป

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

ถ้าฉันเปลี่ยนความสูงเป็น 410 มันจะดำเนินการ cellForItemAtIndexPath


คุณสามารถอธิบายเพิ่มเติมอีกเล็กน้อยได้ไหม สิ่งเดียวกันกำลังเกิดขึ้นสำหรับฉัน
user1010819

ฉันเพิ่งค้นพบว่าคุณต้องระวัง collectionViewContentSize ด้วย
Dimitar Marinov

51
ในกรณีที่คุณใช้ autolayout - อย่าลืมตั้งค่าความสูงบน collectionView - เสียเวลาไปหลายชั่วโมง!
bpn

สำหรับการ จำกัด ความสูงเป็นประวัติการณ์ไม่ได้ผลสำหรับฉัน .. ข้อ จำกัด ตรงกลางแนวนอนทำเคล็ดลับ
Mohamed Emad Hegab

4
หาก collectionView ของคุณถูก จำกัด ไว้ที่ topLayoutGuide ด้วย AutoLayout และไม่ควรเลื่อนไปข้างใต้ NavigationBar ตรวจสอบให้แน่ใจว่าได้ยกเลิกการเลือก Adjust Scroll View InsetsViewController บน Storyboard
Bruno Galinari

96

ในกรณีของฉันมันเป็นเพราะคลาสเลย์เอาต์ของฉันคลาสย่อยไม่ถูกต้องUICollectionViewLayoutแทนที่จะเป็นUICollectionViewFlowLayout


1
ขอบคุณ. Bugger ฉันฉันใช้เวลาหลายปีกับสิ่งนั้น
Rambatino

นี่เป็นปัญหาของฉันเช่นกัน! มันขัดแย้งเล็กน้อยดังนั้นจึงไม่เกิดขึ้นกับฉัน ขอบคุณสำหรับสิ่งนี้!
WendiKidd

เหมือนกับฉัน! มันง่ายมากที่จะมองข้ามสิ่งนั้นไป! ขอบคุณอีกครั้ง
arvidurs

Facepalm มา ณ ที่นี้ขอขอบคุณที่แจ้งเรื่องนี้ (4 ปีที่แล้ว)
Milander

ฉันประสบปัญหาเดียวกัน ขอบคุณ
Piyush Gupta

31

cellForItemAtIndexPath จะไม่ถูกเรียกถ้าคุณไม่ได้ให้ข้อมูลขนาดเนื้อหาในมุมมองคอลเลกชัน

  1. หากคุณใช้เค้าโครง Flow : คุณต้องกำหนดขนาดรายการให้เหมาะสม
  2. หากคุณมีคลาสย่อยเลย์เอาต์แบบกำหนดเองจาก UICollectionViewLayout : ตรวจสอบให้แน่ใจว่าคุณส่งคืนขนาดที่เหมาะสมจากเมธอด collectionViewContentSize

ในกรณีหลังคุณจะสังเกตได้ว่าไม่มีการเรียกlayoutAttributesForElementsRectของคุณ เหตุผลก็คือคุณไม่ได้ระบุขนาดเนื้อหาของคุณและโดยค่าเริ่มต้นขนาดจะเป็น CGSizeZero สิ่งนี้บอกมุมมองคอลเลคชันโดยทั่วไปว่าคุณไม่มีเนื้อหาที่จะวาดดังนั้นจึงไม่ต้องกังวลกับการขอแอตทริบิวต์หรือเซลล์

ดังนั้นเพียงแค่แทนที่ collectionViewContentSize และระบุขนาดที่เหมาะสมก็จะช่วยแก้ปัญหาของคุณได้


1
ตัวอย่างเช่นหากต้องการใช้ขนาดเต็มให้ส่งคืน collectionView.frame.size จาก collectionViewContentSize (ไม่ใช่แค่ collectionView.contentSize ซึ่งมีค่าเริ่มต้นเป็น 0, 0)
Adam Loving

ขอบคุณ! คำตอบนี้ช่วยฉัน b / c ฉันมี UICollectionViewLayout ที่กำหนดเอง หากฉันเริ่มต้นแอปในโปรแกรมจำลองในแนวนอนเซลล์บางเซลล์ไม่ปรากฏในมุมมองเริ่มต้น การแทนที่ขนาดเนื้อหาช่วยแก้ปัญหานี้ให้ฉันได้
Chris Livdahl

1
ขอบคุณ. ในกรณีของฉันcollectionViewContentSizeส่งคืนค่าความกว้าง 0 ไม่ถูกต้องนั่นคือสาเหตุที่cellForItemAtIndexPathไม่ได้รับการเรียก
izerik

16

บางทีฉันอาจจะมองข้ามไป แต่ดูเหมือนว่าคุณไม่มีผู้รับมอบสิทธิ์และแหล่งข้อมูล ในไฟล์ส่วนหัวของคุณตรวจสอบให้แน่ใจว่าคุณได้เพิ่มสิ่งเหล่านี้:

<UICollectionViewDelegate, UICollectionViewDataSource>

และในเมธอด viewDidLoad ของคุณเพิ่มสิ่งนี้:

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

นอกจากนี้หากคุณกำลังโหลดผ่าน. xib ตรวจสอบให้แน่ใจว่าคุณได้เชื่อมต่อ IBOutlet กับ UICollectionView


1
ฉันไม่ได้แสดง แต่ฉันมีผู้รับมอบสิทธิ์และแหล่งข้อมูลที่ระบุไว้ในไฟล์ส่วนหัวแล้ว นอกจากนี้ฉันได้ต่อ IBOutlet เข้ากับ myCollectionView ผู้รับมอบสิทธิ์และแหล่งข้อมูลสำหรับ collectionview นี้ถูกตั้งค่าเป็น FullReceiptViewController สิ่งที่แปลกคือ numberOfItemsInSection (วิธีโปรโตคอลแหล่งข้อมูล) กำลังถูกเรียกและส่งคืนจำนวนเต็มที่มากกว่า 0
IkegawaTaro

อืมเมื่อคุณเปิดแอปพลิเคชันมุมมองคอลเลคชันจะแสดงหรือทำอะไร? ดูเหมือนว่าจะมีบางรายการอยู่ในนั้นถ้า numberOfItemsInSection ส่งกลับค่าที่มากกว่า 0
Anthony Castelli

ขอบคุณที่ติดตาม คอลเลกชันวิวแสดง ... ฉันบอกได้เพราะฉันเปลี่ยนสีพื้นหลัง ฉันเชื่อว่าฉันพบปัญหาแล้ว: [self.myCollectionViewFlowLayout setItemSize: CGSizeMake (320, 548)]; นี่ใหญ่เกินไป ถ้าฉันลดความสูงเป็น 410 ฉันจะเรียกเมธอด cellForItemAtIndexPath ได้
IkegawaTaro

@AnthonyCastelli สวัสดีฉันกำลังประสบปัญหาเดียวกัน numberOfItemsInSection ถูกเรียกให้ป๊อปไปที่ viewController แต่ไม่ใช่ cellForItemsAtIndexPath คุณได้เบาะแสแล้วหรือยัง?
Bhavin Kansagara

16

สำหรับมุมมองที่ซับซ้อนมากขึ้นโปรดตรวจสอบบล็อกนี้ มันช่วยชีวิตฉัน!

self.automaticallyAdjustsScrollViewInsets = NO;

1
ฉันใช้เวลากับเรื่องนี้มาก - และทุกอย่างก็มาถึงจุดนั้น หากใช้สตอรีบอร์ดหรือ XIB ให้ดูที่ตัวควบคุมมุมมองพาเรนต์และยกเลิกการเลือก "Adjust Scroll View Insets" ใน Attribute Inspector ซึ่งเปิดไว้โดยค่าเริ่มต้น ฉันลองคำตอบอื่น ๆ ทั้งหมดแล้ว แต่ก็ไม่ได้ผลมันก็มาถึงสิ่งนี้
etayluz

15

หากคลาสของคุณเป็นคลาสย่อยจาก UICollectionviewController และคุณกำลังสร้าง collectionView โดยใช้โปรแกรมให้ใช้

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

    collectionView?.setCollectionViewLayout(layout, animated: false)

นี่คือคำตอบที่ช่วยแก้ปัญหาของฉันได้! วิธีการแทนที่ func collectionView (_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {<# code #>} ไม่ได้ผลสำหรับฉัน
Mike

8

ฉันใช้การจัดวางอัตโนมัติและในข้อ จำกัด ความสูงของกรณีของฉันหายไป


6

ปัญหาของฉันคือฉันมีมุมมองคอลเลคชัน 2 แบบในมุมมองเดียวกันและทั้งคู่กำลังแชร์UICollectionViewFlowLayoutอินสแตนซ์ที่คำนวณ เมื่อฉันสร้างอินสแตนซ์แยกจากเค้าโครงโฟลว์เดียวกันมันก็ใช้ได้ดี


5

ในกรณีของฉันสิ่งที่ฉันลืมไปอย่างโง่เขลาคือใช้UICollectionViewDataSourceวิธีการโปรโตคอลnumberOfItemsInSectionดังนั้นจึงเป็นอีกสิ่งหนึ่งที่ต้องตรวจสอบ


4

นอกจากนี้ตรวจสอบให้แน่ใจว่าไม่ได้เรียกใช้ reloadData ในขณะที่มุมมองคอลเลกชันกำลังอัปเดตด้วยภาพเคลื่อนไหว (แทรกลบอัปเดตหรือ performBatchUpdates)


4

ในกรณีของฉัน set collectionView.prefetchingEnabled = NO;ช่วยแก้ปัญหาของฉันได้ ใช้งานได้บน iOS 10 เท่านั้น


2
ฉันโหวตคำตอบนั้นเมื่อไม่นานมานี้และวันนี้มันช่วยฉันอีกครั้ง: D คุณสมควรได้รับเกียรติสำหรับคนตอบคนนี้ ขอบคุณอีกครั้ง!
Maciek Czarnik

คำตอบนี้ใช้ได้ผลสำหรับฉัน! ฉันหวังว่าจะมีคำอธิบายว่าทำไมรวมอยู่ด้วยเพราะฉันไม่เคยตั้งค่าเป็นจริงเพื่อเริ่มต้นด้วย
Lance Samaria

3

มันเกิดขึ้นสำหรับฉันเมื่อความสูงของรายการ == 0 โดยการแก้ไขนั้นเรียกเมธอด cellForItem


3

เมื่อสิบนาทีที่แล้วฉันก็เจอปัญหานี้เช่นกันฉันทำพลาดโง่ ๆ

ความตั้งใจของฉันคือใช้ UICollectionViewFlowLayout

แต่เนื่องจากความผิดพลาดฉันจึงใช้ UICollectionViewLayout


3

ในกรณีของฉันการเปลี่ยนความโปร่งแสงของ UINavigationBar เป็น NO ช่วยแก้ปัญหาได้


3

ใน Xcode 7.0.1 เราพบปัญหานี้เมื่อเราคัดลอกสตอรีบอร์ดและโค้ดประกอบจากโปรเจ็กต์อื่น มุมมองคอลเลกชันมีเค้าโครงโฟลว์ที่กำหนดเองซึ่งตั้งอยู่ในสตอรีบอร์ด วิธีแก้ไขคือ:

  • ลบเค้าโครงโฟลว์ใน IB
  • คอมไพล์ / รันแอพ
  • ตั้งค่าเค้าโครงโฟลว์กลับ

ตอนนี้ใช้งานได้แล้ว :)


2

ตรวจสอบให้แน่ใจว่าnumberOfSectionsInCollectionViewส่งคืนจำนวนเต็มบวกเช่นกัน

ต้องมีอย่างน้อยหนึ่งส่วนในคอลเล็กชัน


2

ตรวจสอบให้แน่ใจว่า - (NSInteger) collectionView: numberOfItemsInSection: กำลังส่งคืนค่าที่เป็นบวก (อ่านแล้วมากกว่าศูนย์) อาจเป็นเรื่องของการวาง [self.collectionView reloadData]; ในตัวจัดการความสมบูรณ์


2

ฉันลืมตั้งค่ามาสก์การปรับขนาดอัตโนมัติเป็นเท็จในมุมมองคอลเลกชัน:

collectionView.translatesAutoresizingMaskIntoConstraints = false

2

มันสามารถตระหนักถึงปัญหาเค้าโครง ตรวจสอบคำเตือนเค้าโครงจากคอนโซลหากมี


2

ในกรณีของฉันมุมมองคอลเลกชันไม่สามารถมองเห็นได้อย่างสมบูรณ์ในมุมมองระดับบนสุดเนื่องจากข้อ จำกัด ของการจัดวางอัตโนมัติ ดังนั้นการแก้ไขข้อ จำกัด จึงทำให้มุมมองคอลเลกชันมองเห็นได้ทั้งหมดและเรียกเซลล์ForItemAtIndexPath


2

ในสตอรีบอร์ด / xib เซลล์คุณสมบัติ UICollectionView ขนาดต้องไม่เป็น {0, 0}


2

หากคุณใช้โปรโตคอลมุมมองคอลเลกชันคุณต้องเชื่อมต่อCollectionViewDataSourceและCollectionViewDelegateโปรโตคอลกับ ViewController ของคุณ ช่องทางการสร้างอินเทอร์เฟซ


1

เหมือนกันเกิดขึ้นกับฉัน ฉันมี UICollectionViews 2 ตัวและฉันลบหนึ่งครั้งเนื่องจากฉันไม่ต้องการสิ่งนั้น หลังจากนั้นฉันก็รู้ว่า CellForItemAtIndexPath ไม่ได้รับการเรียกใช้ แต่วิธีอื่นที่จำเป็น ฉันลองทำทุกอย่างข้างต้นแล้ว แต่ฉันก็ใช้เวทมนตร์มาตรฐาน ลบมุมมองคอลเลคชันออกจากสตอรีบอร์ดและเพิ่มอีกครั้ง จากนั้นก็เริ่มทำงาน ไม่แน่ใจว่าทำไมและฉันไม่มีคำอธิบาย แต่อาจมีปัญหาการเชื่อมต่อ


ฉันคัดลอก UICollectionView จาก UIViewController อื่นในสตอรี่บอร์ด ฉันลบ CollectionView และเพิ่มอีกครั้งเพื่อให้ใช้งานได้ ขอบคุณสำหรับคำตอบ.
Drunken Daddy

1

เพิ่งแก้ไขปัญหานี้สำหรับสถานการณ์ที่ค่อนข้างเฉพาะเจาะจง

ในกรณีของฉันฉันเริ่มต้น UICollectionViewController ด้วยตนเองใน ViewController หลักจากนั้นเพิ่มมุมมองของ UICollectionViewController เป็นมุมมองย่อย

ฉันแก้ไขปัญหาโดยเรียก 'setNeedsLayout' และ / หรือ 'setNeedsDisplay' บน collectionView ใน viewDidAppear ของผู้ปกครอง:

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

1

เมื่อใช้โปรดUICollectionViewDelegateFlowLayoutระวังสิ่งที่ฟังก์ชันนี้ส่งคืน ทั้งสองwidthและควรมากกว่าheight 0ฉันใช้windowเป็นการอ้างอิงเฟรม แต่เนื่องจากหน้าต่างลำดับชั้นมุมมองที่ซับซ้อนอยู่nilที่รันไทม์ UIScreen.main.boundsหากคุณจำเป็นต้องปรับความกว้างขององค์ประกอบตามการใช้งานกว้างของหน้าจอ

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

1

ฉันมีปัญหาที่คล้ายกัน แต่กลับกันcellForItemAtIndexPathจะเรียกเมื่อจำนวนรายการ> 1 แต่ไม่ใช่เมื่อมีเพียงรายการเดียว ฉันลองใช้วิธีแก้ปัญหาที่นำเสนอมากมายที่นี่และคล้ายกับหลายข้อที่ฉันพบว่าเกี่ยวข้องกับการปรับขนาดรายการ สำหรับผมการแก้ปัญหาคือการเปลี่ยนขนาดประมาณการของUICollectionViewจากอัตโนมัติที่จะกำหนดเอง

กำหนดขนาดโดยประมาณเป็นกำหนดเอง


1

ในกรณีของฉันฉันมีcollectionViewในกับUIStackView alignment = .centerดังนั้นจึงcollectionViewไม่มีความกว้าง เมื่อตั้งค่าstackView.alignmentการ.fillทุกอย่างถูกปรับ


0

สำหรับฉันฉันอัปเดตความสูงของ self.view (superview ของ collectionView) ผ่านทางอัตโนมัติและต้องโทรlayoutIfNeededหลังจากนั้น

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

0

ในกรณีของฉันฉันต้องปรับขนาดเนื้อหาโดยประมาณ ขนาดเนื้อหาไม่ได้ทำ

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

-1

ฉันจมลงไปเล็กน้อยกับปัญหานี้ที่มาพร้อมกับ CollectionView ในคอนโทรลเลอร์มุมมองที่มีอยู่ซึ่งโหลดจากสตอรี่บอร์ด ฉันลงเอยด้วยการลบตัวควบคุมมุมมองที่มีอยู่และสร้างขึ้นใหม่ในกระดานเรื่องราวและสิ่งนี้ดูเหมือนจะกำจัดปัญหาได้ ฉันเดาว่ามีความเสียหายบางอย่างของสตอรีบอร์ดที่เกิดขึ้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.