Chỉ định một thứ nguyên của ô trong UICollectionView bằng cách sử dụng Bố cục tự động


113

Trong iOS 8, UICollectionViewFlowLayouthỗ trợ tự động thay đổi kích thước ô dựa trên kích thước nội dung của chính chúng. Điều này thay đổi kích thước các ô theo cả chiều rộng và chiều cao theo nội dung của chúng.

Có thể chỉ định một giá trị cố định cho chiều rộng (hoặc chiều cao) của tất cả các ô và cho phép các thứ nguyên khác thay đổi kích thước không?

Đối với một ví dụ đơn giản, hãy xem xét một nhãn nhiều dòng trong một ô với các ràng buộc định vị nó ở các cạnh của ô. Nhãn nhiều dòng có thể được thay đổi kích thước theo nhiều cách khác nhau để phù hợp với văn bản. Ô phải lấp đầy chiều rộng của chế độ xem bộ sưu tập và điều chỉnh chiều cao cho phù hợp. Thay vào đó, các ô được định kích thước một cách lộn xộn và nó thậm chí gây ra sự cố khi kích thước ô lớn hơn kích thước không thể cuộn của chế độ xem bộ sưu tập.


iOS 8 giới thiệu phương pháp systemLayoutSizeFittingSize: withHorizontalFittingPriority: verticalFittingPriority:Đối với mỗi ô trong chế độ xem bộ sưu tập, bố cục gọi phương thức này trên ô, truyền kích thước ước tính. Điều có ý nghĩa đối với tôi là ghi đè phương thức này trên ô, chuyển kích thước được cho và đặt ràng buộc ngang thành bắt buộc và mức ưu tiên thấp cho ràng buộc dọc. Bằng cách này, kích thước ngang được cố định với giá trị được đặt trong bố cục và kích thước dọc có thể linh hoạt.

Một cái gì đó như thế này:

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    UICollectionViewLayoutAttributes *attributes = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
    attributes.size = [self systemLayoutSizeFittingSize:layoutAttributes.size withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityFittingSizeLevel];
    return attributes;
}

Tuy nhiên, các kích thước được đưa ra bởi phương pháp này là hoàn toàn lạ. Tài liệu về phương pháp này rất không rõ ràng đối với tôi và đề cập đến việc sử dụng các hằng số UILayoutFittingCompressedSize UILayoutFittingExpandedSizechỉ đại diện cho kích thước bằng 0 và một kích thước khá lớn.

sizetham số của phương pháp này thực sự chỉ là một cách để vượt qua trong hai hằng số? Không có cách nào để đạt được hành vi mà tôi mong đợi là có được chiều cao thích hợp với một kích thước nhất định?


Các giải pháp thay thế

1) Thêm các ràng buộc sẽ chỉ định chiều rộng cụ thể cho ô để đạt được bố cục chính xác. Đây là một giải pháp kém vì ràng buộc đó phải được đặt thành kích thước của chế độ xem bộ sưu tập của ô mà nó không có tham chiếu an toàn. Giá trị cho ràng buộc đó có thể được chuyển vào khi ô được định cấu hình, nhưng điều đó cũng có vẻ hoàn toàn phản trực giác. Điều này cũng rất khó xử vì việc thêm các ràng buộc trực tiếp vào một ô hoặc chế độ xem nội dung của nó gây ra nhiều vấn đề.

2) Sử dụng chế độ xem bảng. Chế độ xem bảng hoạt động theo cách này ngoài hộp vì các ô có chiều rộng cố định, nhưng điều này sẽ không phù hợp với các trường hợp khác như bố cục iPad với các ô có chiều rộng cố định trong nhiều cột.

Câu trả lời:


135

Có vẻ như những gì bạn đang yêu cầu là một cách sử dụng UICollectionView để tạo ra một bố cục giống như UITableView. Nếu đó thực sự là những gì bạn muốn, cách phù hợp để làm điều này là với một lớp con UICollectionViewLayout tùy chỉnh (có thể giống như SBTableLayout ).

Mặt khác, nếu bạn thực sự hỏi liệu có cách nào hợp lý để làm điều này với UICollectionViewFlowLayout mặc định, thì tôi tin rằng không có cách nào. Ngay cả với các ô tự định cỡ của iOS8, nó không đơn giản. Vấn đề cơ bản, như bạn nói, là bộ máy của bố cục luồng không có cách nào để sửa một thứ nguyên và để thứ nguyên khác phản hồi. (Ngoài ra, ngay cả khi bạn có thể, sẽ có thêm sự phức tạp xung quanh việc cần hai lần chuyển bố cục để định kích thước các nhãn nhiều dòng. Điều này có thể không phù hợp với cách các ô tự định kích thước muốn tính toán tất cả kích thước thông qua một lệnh gọi tới systemLayoutSizeFittingSize.)

Tuy nhiên, nếu bạn vẫn muốn tạo một bố cục giống như chế độ xem bảng với bố cục dòng, với các ô xác định kích thước riêng của chúng và phản hồi tự nhiên với chiều rộng của chế độ xem bộ sưu tập, tất nhiên là có thể. Vẫn còn đường lộn xộn. Tôi đã làm điều đó với một "ô định cỡ", tức là, một UICollectionViewCell không hiển thị mà bộ điều khiển chỉ giữ lại để tính toán kích thước ô.

Có hai phần trong cách tiếp cận này. Phần đầu tiên dành cho đại biểu chế độ xem bộ sưu tập để tính toán kích thước ô chính xác, bằng cách lấy chiều rộng của chế độ xem bộ sưu tập và sử dụng ô định cỡ để tính toán chiều cao của ô.

Trong UICollectionViewDelegateFlowLayout của bạn, bạn triển khai một phương pháp như sau:

func collectionView(collectionView: UICollectionView,
  layout collectionViewLayout: UICollectionViewLayout,
  sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
  // NOTE: here is where we say we want cells to use the width of the collection view
   let requiredWidth = collectionView.bounds.size.width

   // NOTE: here is where we ask our sizing cell to compute what height it needs
  let targetSize = CGSize(width: requiredWidth, height: 0)
  /// NOTE: populate the sizing cell's contents so it can compute accurately
  self.sizingCell.label.text = items[indexPath.row]
  let adequateSize = self.sizingCell.preferredLayoutSizeFittingSize(targetSize)
  return adequateSize
}

Điều này sẽ làm cho chế độ xem bộ sưu tập đặt chiều rộng của ô dựa trên chế độ xem bộ sưu tập bao quanh, nhưng sau đó yêu cầu ô định cỡ tính toán chiều cao.

Phần thứ hai là để ô định cỡ sử dụng các ràng buộc AL của chính nó để tính chiều cao. Điều này có thể khó hơn mức cần thiết, vì cách thức hiệu quả của UILabel nhiều dòng đòi hỏi một quy trình bố trí hai giai đoạn. Công việc được thực hiện theo phương thức preferredLayoutSizeFittingSizenhư sau:

 /*
 Computes the size the cell will need to be to fit within targetSize.

 targetSize should be used to pass in a width.

 the returned size will have the same width, and the height which is
 calculated by Auto Layout so that the contents of the cell (i.e., text in the label)
 can fit within that width.

 */
 func preferredLayoutSizeFittingSize(targetSize:CGSize) -> CGSize {

   // save original frame and preferredMaxLayoutWidth
   let originalFrame = self.frame
   let originalPreferredMaxLayoutWidth = self.label.preferredMaxLayoutWidth

   // assert: targetSize.width has the required width of the cell

   // step1: set the cell.frame to use that width
   var frame = self.frame
   frame.size = targetSize
   self.frame = frame

   // step2: layout the cell
   self.setNeedsLayout()
   self.layoutIfNeeded()
   self.label.preferredMaxLayoutWidth = self.label.bounds.size.width

   // assert: the label's bounds and preferredMaxLayoutWidth are set to the width required by the cell's width

   // step3: compute how tall the cell needs to be

   // this causes the cell to compute the height it needs, which it does by asking the 
   // label what height it needs to wrap within its current bounds (which we just set).
   let computedSize = self.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

   // assert: computedSize has the needed height for the cell

   // Apple: "Only consider the height for cells, because the contentView isn't anchored correctly sometimes."
   let newSize = CGSize(width:targetSize.width,height:computedSize.height)

   // restore old frame and preferredMaxLayoutWidth
   self.frame = originalFrame
   self.label.preferredMaxLayoutWidth = originalPreferredMaxLayoutWidth

   return newSize
 }

(Mã này được điều chỉnh từ mã mẫu của Apple từ mã mẫu của phiên WWDC2014 trên "Chế độ xem bộ sưu tập nâng cao".)

Một vài điểm cần lưu ý. Nó sử dụng layoutIfNeeded () để buộc bố trí toàn bộ ô, nhằm tính toán và thiết lập chiều rộng của nhãn. Nhưng điều đó vẫn chưa đủ. Tôi tin rằng bạn cũng cần thiết lập preferredMaxLayoutWidthđể nhãn sẽ sử dụng chiều rộng đó với Bố cục Tự động. Và chỉ khi đó, bạn mới có thể sử dụng systemLayoutSizeFittingSizeđể yêu cầu ô tính toán chiều cao của nó trong khi tính đến nhãn.

Tôi có thích cách tiếp cận này không? Không!! Nó cảm thấy quá phức tạp và nó phải bố trí hai lần. Nhưng miễn là hiệu suất không trở thành vấn đề, tôi thà thực hiện bố cục hai lần trong thời gian chạy hơn là phải xác định nó hai lần trong mã, đây dường như là giải pháp thay thế duy nhất.

Hy vọng của tôi là cuối cùng các tế bào tự định cỡ sẽ hoạt động khác đi và điều này sẽ trở nên đơn giản hơn rất nhiều.

Dự án ví dụ hiển thị nó tại nơi làm việc.

Nhưng tại sao không chỉ sử dụng các tế bào tự định cỡ?

Về lý thuyết, các cơ sở mới của iOS8 cho "tế bào tự định cỡ" sẽ khiến điều này trở nên không cần thiết. Nếu bạn đã xác định một ô bằng Bố cục Tự động (AL), thì chế độ xem bộ sưu tập phải đủ thông minh để cho phép nó tự kích thước và sắp xếp chính xác. Trong thực tế, tôi chưa thấy bất kỳ ví dụ nào làm cho điều này hoạt động với các nhãn nhiều dòng. Tôi nghĩ điều này một phần là do cơ chế tế bào tự định cỡ vẫn còn nhiều lỗi.

Nhưng tôi dám cá rằng đó chủ yếu là do sự phức tạp thông thường của Bố cục Tự động và nhãn, đó là Nhãn dán yêu cầu một quy trình bố trí cơ bản gồm hai bước. Tôi không rõ làm thế nào bạn có thể thực hiện cả hai bước với các ô tự định cỡ.

Và như tôi đã nói, đây thực sự là một công việc cho một bố cục khác. Nó là một phần bản chất của bố cục luồng là nó định vị những thứ có kích thước, thay vì cố định chiều rộng và cho phép chúng chọn chiều cao của chúng.

Và những gì về ưu tiênLayoutAttributesFittingAttributes:?

Các preferredLayoutAttributesFittingAttributes:phương pháp là một cá trích đỏ, tôi nghĩ. Điều đó chỉ được sử dụng với cơ chế tế bào tự định cỡ mới. Vì vậy, đây không phải là câu trả lời miễn là cơ chế đó không đáng tin cậy.

Và có gì với systemlayoutSizeFittingSize:?

Bạn nói đúng, tài liệu khó hiểu.

Các tài liệu trên systemLayoutSizeFittingSize:systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:cả hai đều gợi ý rằng bạn chỉ nên vượt qua UILayoutFittingCompressedSizeUILayoutFittingExpandedSizenhư targetSize. Tuy nhiên, bản thân chữ ký phương thức, chú thích tiêu đề và hành vi của các hàm cho thấy rằng chúng đang phản hồi với giá trị chính xác của targetSizetham số.

Trên thực tế, nếu bạn đặt UICollectionViewFlowLayoutDelegate.estimatedItemSize, để kích hoạt cơ chế ô tự định cỡ mới, giá trị đó dường như được chuyển vào dưới dạng targetSize. Và UILabel.systemLayoutSizeFittingSizedường như trả về các giá trị giống hệt như UILabel.sizeThatFits. Điều này thật đáng ngờ, vì đối số tới systemLayoutSizeFittingSizeđược cho là một mục tiêu thô và đối số tới sizeThatFits:được cho là kích thước vòng tròn tối đa.

Nhiêu tai nguyên hơn

Mặc dù thật đáng buồn khi nghĩ rằng một yêu cầu thường xuyên như vậy cần phải có "tài nguyên nghiên cứu", tôi nghĩ nó đúng. Các ví dụ và thảo luận hay là:


Tại sao bạn đặt khung trở lại khung cũ?
vrwim

Tôi làm điều đó để hàm chỉ có thể được sử dụng để xác định kích thước bố cục ưa thích của chế độ xem, mà không ảnh hưởng đến trạng thái bố cục của chế độ xem mà bạn gọi nó. Thực tế, điều này không liên quan nếu bạn đang giữ chế độ xem này chỉ với mục đích tính toán bố cục. Ngoài ra, những gì tôi làm ở đây là không đủ. Chỉ khôi phục khung không thực sự khôi phục nó về trạng thái trước đó, vì việc thực hiện bố cục có thể đã sửa đổi bố cục của các lần xem phụ.
algal

1
Đây là một mớ hỗn độn đối với một số thứ mà mọi người đã làm kể từ ios6. Apple luôn đưa ra một số cách nhưng nó không bao giờ đúng.
GregP

1
Bạn có thể khởi tạo ô định cỡ theo cách thủ công trong viewDidLoad và giữ nó để xem một thuộc tính tùy chỉnh. Nó chỉ có một ô nên rẻ. Vì bạn chỉ sử dụng nó để định kích thước và bạn đang quản lý tất cả tương tác với nó, nó không cần tham gia vào cơ chế tái sử dụng ô của chế độ xem bộ sưu tập, vì vậy bạn không cần lấy nó từ chính chế độ xem bộ sưu tập.
tảo

1
Làm thế quái nào mà các tế bào tự định cỡ vẫn có thể bị phá vỡ ?!
Reuben Scratton

50

Có một cách rõ ràng hơn để làm điều này so với một số câu trả lời khác ở đây và nó hoạt động tốt. Nó phải hiệu quả (chế độ xem bộ sưu tập tải nhanh, không có bố cục tự động không cần thiết đi qua, v.v.) và không có bất kỳ 'con số kỳ diệu' nào như chiều rộng chế độ xem bộ sưu tập cố định. Thay đổi kích thước chế độ xem bộ sưu tập, ví dụ như khi xoay, và sau đó làm mất hiệu lực của bố cục cũng sẽ hoạt động tốt.

1. Tạo lớp con bố cục luồng sau

class HorizontallyFlushCollectionViewFlowLayout: UICollectionViewFlowLayout {

    // Don't forget to use this class in your storyboard (or code, .xib etc)

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
        let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)?.copy() as? UICollectionViewLayoutAttributes
        guard let collectionView = collectionView else { return attributes }
        attributes?.bounds.size.width = collectionView.bounds.width - sectionInset.left - sectionInset.right
        return attributes
    }

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let allAttributes = super.layoutAttributesForElementsInRect(rect)
        return allAttributes?.flatMap { attributes in
            switch attributes.representedElementCategory {
            case .Cell: return layoutAttributesForItemAtIndexPath(attributes.indexPath)
            default: return attributes
            }
        }
    }
}

2. Đăng ký chế độ xem bộ sưu tập của bạn để định cỡ tự động

// The provided size should be a plausible estimate of the actual
// size. You can set your item size in your storyboard
// to a good estimate and use the code below. Otherwise,
// you can provide it manually too, e.g. CGSize(width: 100, height: 100)

flowLayout.estimatedItemSize = flowLayout.itemSize

3. Sử dụng chiều rộng xác định trước + chiều cao tùy chỉnh trong lớp con ô của bạn

override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    layoutAttributes.bounds.size.height = systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
    return layoutAttributes
}

8
Đây là câu trả lời tuyệt vời nhất mà tôi đã tìm thấy về chủ đề tự định cỡ. Cảm ơn Jordan!
haik.ampardjian

1
Không thể làm cho điều này hoạt động trên iOS (9.3). Trên 10 nó hoạt động tốt. Ứng dụng bị lỗi trên _updateVbrokenCells (đệ quy vô hạn?). openradar.me/25303115
cristiano2lopes

@ cristiano2lopes nó hoạt động tốt với tôi trên iOS 9.3. Đảm bảo rằng bạn đang cung cấp một ước tính hợp lý và đảm bảo rằng các ràng buộc ô của bạn được thiết lập để giải quyết đúng kích thước.
Jordan Smith

Điều này hoạt động tuyệt vời. Tôi đang sử dụng Xcode 8 và đã thử nghiệm trong iOS 9.3.3 (thiết bị vật lý) và nó không bị lỗi! Hoạt động tuyệt vời. Chỉ cần đảm bảo ước tính của bạn là tốt!
hahmed

1
@JordanSmith Tính năng này không hoạt động trong iOS 10. Bạn có bản demo mẫu nào không. Tôi đã thử rất nhiều cách để thực hiện chiều cao ô trong chế độ xem bộ sưu tập dựa trên nội dung của nó nhưng không có gì. Tôi đang sử dụng bố trí tự động trong iOS 10 và sử dụng nhanh chóng 3.
Ekta Padaliya

6

Một cách đơn giản để thực hiện điều đó trong iOS 9 bằng một vài dòng mã - ví dụ theo chiều ngang (sửa chiều cao của nó thành chiều cao của Chế độ xem bộ sưu tập):

Kết hợp Bố cục Luồng Chế độ xem Bộ sưu tập của bạn bằng một estimatedItemSizeđể bật ô tự định kích thước:

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.estimatedItemSize = CGSizeMake(1, 1);

Triển khai Ủy nhiệm Bố cục Chế độ xem Bộ sưu tập (trong Bộ điều khiển Chế độ xem của bạn hầu hết thời gian) , collectionView:layout:sizeForItemAtIndexPath:. Mục tiêu ở đây là đặt chiều cao (hoặc chiều rộng) cố định cho thứ nguyên Chế độ xem bộ sưu tập. Giá trị 10 có thể là bất kỳ giá trị nào, nhưng bạn nên đặt nó thành giá trị không phá vỡ các ràng buộc:

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return CGSizeMake(10, CGRectGetHeight(collectionView.bounds));
}

Ghi đè preferredLayoutAttributesFittingAttributes:phương pháp ô tùy chỉnh của bạn , phần này thực sự tính toán chiều rộng ô động của bạn dựa trên các ràng buộc Bố cục Tự động và chiều cao bạn vừa đặt:

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
    UICollectionViewLayoutAttributes *attributes = [layoutAttributes copy];
    float desiredWidth = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].width;
    CGRect frame = attributes.frame;
    frame.size.width = desiredWidth;
    attributes.frame = frame;
    return attributes;
}

Bạn có biết liệu trên iOS9, phương pháp đơn giản hơn này có hoạt động chính xác khi ô bao gồm nhiều dòng UILabel, mà việc ngắt dòng ảnh hưởng đến chiều cao nội tại của ô không? Đây là một trường hợp phổ biến được sử dụng để yêu cầu tất cả các lật ngược mà tôi mô tả. Tôi tự hỏi liệu iOS đã khắc phục nó hay chưa kể từ câu trả lời của tôi.
algal

2
@algal Đáng buồn thay, câu trả lời là không.
jamesk

4

Hãy thử sửa chiều rộng của bạn trong các thuộc tính bố cục ưa thích:

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    UICollectionViewLayoutAttributes *attributes = [[super preferredLayoutAttributesFittingAttributes:layoutAttributes] copy];
    CGSize newSize = [self systemLayoutSizeFittingSize:CGSizeMake(FIXED_WIDTH,layoutAttributes.size) withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityFittingSizeLevel];
    CGRect newFrame = attr.frame;
    newFrame.size.height = size.height;
    attr.frame = newFrame;
    return attr;
}

Đương nhiên, bạn cũng muốn đảm bảo rằng bạn thiết lập bố cục của mình một cách chính xác để:

UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *) self.collectionView.collectionViewLayout;
flowLayout.estimatedItemSize = CGSizeMake(FIXED_WIDTH, estimatedHeight)];

Đây là một cái gì đó tôi đưa trên Github sử dụng các ô có chiều rộng không đổi và hỗ trợ kiểu động để chiều cao của các ô cập nhật khi kích thước phông chữ hệ thống thay đổi.


Trong đoạn mã này, bạn gọi systemLayoutSizeFittingSize:. Bạn đã quản lý để làm cho điều này hoạt động mà không cần đặt ưu tiênMaxLayoutWidth ở đâu đó không? Theo kinh nghiệm của tôi, nếu bạn không đặt ưu tiênMaxLayoutWidth, thì bạn cần thực hiện thêm bố cục thủ công, ví dụ: bằng cách ghi đè sizeThatFits: với các phép tính tái tạo logic của các ràng buộc bố cục tự động được xác định ở nơi khác.
algal

@algal preferMaxLayoutWidth là thuộc tính trên UILabel? Không hoàn toàn chắc chắn điều đó có liên quan như thế nào?
Daniel Galasko

Giáo sư! Điểm tốt, nó không phải! Tôi chưa bao giờ xử lý điều này với UITextView, vì vậy tôi không nhận ra rằng các API của chúng khác nhau ở đó. Có vẻ như UITextView.systemLayoutSizeFittingSize tôn trọng khung của nó vì nó không có nội tạiContentSize. Nhưng UILabel.systemLayoutSizeFittingSize bỏ qua khung, vì nó có nội tạiContentSize, do đó, cần phải có favouriteMaxLayoutWidth để lấy nội tạiContentSize để hiển thị chiều cao được bao bọc của nó với AL. Vẫn có vẻ như UITextView sẽ cần hai lần chuyển hoặc bố cục thủ công, nhưng tôi không nghĩ rằng tôi hiểu hết điều này.
algal

@algal Tôi có thể đồng ý, tôi cũng đã gặp một số khó khăn khi sử dụng UILabel. Cài đặt chiều rộng ưa thích của nó giải quyết được vấn đề nhưng sẽ rất tuyệt nếu có một cách tiếp cận năng động hơn vì chiều rộng này cần phải mở rộng với chế độ siêu quan của nó. Hầu hết các dự án của tôi không sử dụng tài sản được ưa thích, tôi thường sử dụng đó như là một sửa chữa nhanh chóng như theres luôn luôn là một vấn đề sâu sắc hơn
Daniel Galasko

0

CÓ, nó có thể được thực hiện bằng cách sử dụng bố cục tự động theo lập trình và bằng cách thiết lập các ràng buộc trong bảng phân cảnh hoặc xib. Bạn cần thêm ràng buộc để kích thước chiều rộng không đổi và đặt chiều cao lớn hơn hoặc bằng.
http://www.thinkandbuild.it/learn-to-love-auto-layout-programmatically/

http://www.cocoanetics.com/2013/08/variable-sized-items-in-uicollectionview/
Hy vọng điều này sẽ hữu ích và giải quyết vấn đề của bạn.


3
Điều này sẽ hoạt động cho một giá trị chiều rộng tuyệt đối, nhưng trong trường hợp bạn muốn ô luôn là chiều rộng đầy đủ của chế độ xem bộ sưu tập, nó sẽ không hoạt động.
Michael Waterfall

@MichaelWaterfall Tôi đã quản lý để làm cho nó hoạt động với chiều rộng đầy đủ bằng cách sử dụng Tự động thanh toán. Tôi đã thêm một ràng buộc chiều rộng vào chế độ xem nội dung của mình bên trong ô. Sau đó, trong cellForItemAtIndexPathcập nhật các hạn chế: cell.constraintItemWidth.constant = UIScreen.main.bounds.width. Ứng dụng của tôi chỉ ở chế độ portait. Bạn có thể muốn reloadDatasau khi thay đổi hướng để cập nhật ràng buộc.
Flitskikker
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.