2012-12-06 42 views
40

Các ô UICollectionView của tôi chứa UILabels với văn bản nhiều dòng. Tôi không biết số height của UICollectionViewCells cho đến khi văn bản được đặt trên UILabel.Thay đổi kích thước các ô UICollectionView sau khi dữ liệu của chúng được đặt

-(CGSize)collectionView:(UICollectionView *)collectionView 
       layout:(UICollectionViewLayout*)collectionViewLayout 
sizeForItemAtIndexPath:(NSIndexPath *)indexPath; 

Là phương pháp ban đầu tôi nhìn vào kích thước các UICollectionViewCells, tuy nhiên điều này được gọi là TRƯỚC KHI các tế bào được tạo ra trong những UIStoryboard. Có cách nào để bố trí các bộ sưu tập và kích thước các tế bào SAU họ đã được trả lại, và tôi biết kích thước thực tế của tế bào?

+0

Điều này giống như giải pháp tốt nhất cho vấn đề này - http: // stackoverflow.com/a/19518480/2147976 – codeburn

Trả lời

65

Tôi nghĩ rằng bạn đang tìm kiếm invalidateLayout phương pháp bạn có thể gọi vào .collectionViewLayout tài sản của UICollectionView của bạn. Phương pháp này sẽ tái tạo bố cục của bạn, trong trường hợp của bạn có nghĩa là cũng gọi -collectionView: layout: sizeForItemAtIndexPath:, đây là nơi phù hợp để phản ánh kích thước mục mong muốn của bạn. Jirune chỉ đúng hướng về cách tính chúng.

Ví dụ về cách sử dụng invalidateLayout có thể được tìm thấy here. Đồng thời tham khảo tài liệu UICollectionViewLayout về phương pháp đó:

Vô hiệu hóa bố cục hiện tại và kích hoạt bản cập nhật bố cục.

Thảo luận:

Bạn có thể gọi phương pháp này bất cứ lúc nào để cập nhật các thông tin bố trí. Phương thức này làm mất hiệu lực bố cục của khung nhìn bộ sưu tập và trả về ngay lập tức. Do đó, bạn có thể gọi phương thức này nhiều lần từ cùng một khối mã mà không kích hoạt nhiều bản cập nhật bố cục. Bản cập nhật bố cục thực tế xảy ra trong chu kỳ cập nhật bố cục xem tiếp theo.

Edit:

Đối xem bộ sưu tập kịch bản, trong đó có những hạn chế bố trí tự động, bạn cần phải ghi đè viewDidLayoutSubviews phương pháp UIViewController và gọi bố trí xem invalidateLayout bộ sưu tập trong phương pháp này.

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 
    [yourCollectionView.collectionViewLayout invalidateLayout]; 
} 
+0

Tôi đang theo dõi cách thực hiện của bạn, có một vấn đề tôi gặp: sau khi gọi 'invalidateLayout' đôi khi các tế bào biến mất/vô hình, vì vậy tôi không thể lấy chúng trong' sizeForItemAtIndexPath' với 'cellForItemAtIndexPath'. Btw tôi sử dụng các tế bào để có được kích thước của họ, tôi không có một cửa hàng riêng biệt cho nó. –

+0

cool thx! tốt hơn nhiều so với tải lại dữ liệu – Raegtime

+0

Tuyệt vời! Đã bị mắc kẹt trên chiều rộng di động mà không thay đổi vì nó được gán bởi bố cục tự động, nhưng sau khi đọc giải pháp này tôi đã tìm ra điều đó. P.S. Tôi đặt mã cho vấn đề bố trí tự động, hy vọng bạn không nhớ. – Kampai

4

Xin chào ở chính phương thức delegate ở trên, bạn có thể tính kích thước UILabel bằng cách sử dụng cách dưới đây và trả lại UICollectionViewCellsize dựa trên phép tính đó.

// Calculate the expected size based on the font and 
    // linebreak mode of your label 
    CGSize maximumLabelSize = CGSizeMake(9999,9999); 

    CGSize expectedLabelSize = 
    [[self.dataSource objectAtIndex:indexPath.item] 
      sizeWithFont:[UIFont fontWithName:@"Arial" size:18.0f] 
     constrainedToSize:maximumLabelSize 
      lineBreakMode:NSLineBreakByWordWrapping]; 
3

lớp con UICollectionViewCell và ghi đè layoutSubviews như thế này

hướng bạn sẽ tế bào neo ở đầu và đuôi cạnh để collectionView

override func layoutSubviews() { 
     super.layoutSubviews() 

     self.frame = CGRectMake(0, self.frame.origin.y, self.superview!.frame.size.width, self.frame.size.height) 
    } 
0
- (void)viewDidLoad { 
    self.collectionView.prefetchingEnabled = NO; 
} 

Trong iOS 10, prefetchingEnabledYES theo mặc định . Khi YES, chế độ xem bộ sưu tập yêu cầu các ô trước khi chúng được hiển thị. Nó dẫn đến sự cố trong iOS 10

+1

Trong khi đoạn mã này được chào đón, và có thể cung cấp một số trợ giúp, nó sẽ được [cải thiện rất nhiều nếu nó bao gồm một lời giải thích] (// meta.stackexchange.com/q/114762) của * how * và * why * this giải quyết vấn đề. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ là người hỏi ngay bây giờ! Vui lòng [sửa] câu trả lời của bạn để thêm giải thích và đưa ra chỉ dẫn về những giới hạn và giả định được áp dụng. –

+0

@TobySpeight Trong iOS10, prefetchingEnabled là YES theo mặc định. Khi CÓ, chế độ xem bộ sưu tập yêu cầu các ô trước khi chúng được hiển thị. Nó dẫn đến sự cố trong iOS10 –

+0

Điều đó giống như một lời giải thích tốt - vui lòng ** [sửa] ** câu trả lời của bạn để kết hợp nó. Cảm ơn! –

Các vấn đề liên quan