2015-12-02 15 views
5

tôi có một dự án đơn giản với một kịch bản chỉ chứa một đơn một UICollectionViewController, được xây dựng với Xcode 7.1.1 dành cho iOS 9,1tế bào UICollectionView thay đổi kích thước khi xóa mục có estimatedItemSize

class ViewController: UICollectionViewController { 

    var values = ["tortile", "jetty", "tisane", "glaucia", "formic", "agile", "eider", "rooter", "nowhence", "hydrus", "outdo", "godsend", "tinkler", "lipscomb", "hamlet", "unbreeched", "fischer", "beastings", "bravely", "bosky", "ridgefield", "sunfast", "karol", "loudmouth", "liam", "zunyite", "kneepad", "ashburn", "lowness", "wencher", "bedwards", "guaira", "afeared", "hermon", "dormered", "uhde", "rusher", "allyou", "potluck", "campshed", "reeda", "bayonne", "preclose", "luncheon", "untombed", "northern", "gjukung", "bratticed", "zeugma", "raker"] 

    @IBOutlet weak var flowLayout: UICollectionViewFlowLayout! 
    override func viewDidLoad() { 
     super.viewDidLoad()   
     flowLayout.estimatedItemSize = CGSize(width: 10, height: 10) 
    } 

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return values.count 
    } 

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as! MyCell 
     cell.name = values[indexPath.row] 
     return cell 
    } 

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
     values.removeAtIndex(indexPath.row) 
     collectionView.deleteItemsAtIndexPaths([indexPath]) 
    } 
} 

class MyCell: UICollectionViewCell { 

    @IBOutlet weak var label: UILabel! 

    var name: String? { 
     didSet { 
      label.text = name 
     } 
    } 
} 

Khi xóa các tế bào từ giao diện bộ sưu tập , tất cả các ô còn lại đều hoạt ảnh với estimatedItemSize và sau đó hoán đổi lại thành kích thước chính xác.

enter image description here

Điều thú vị là, điều này tạo ra những cảnh báo hạn chế bố trí tự động cho mỗi tế bào khi các hình ảnh động xảy ra:

2015-12-02 14:30:45.236 CollectionTest[1631:427853] Unable to simultaneously satisfy constraints. 
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
     (1) look at each constraint and try to figure out which you don't expect; 
     (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x14556f780 h=--& v=--& H:[UIView:0x1456ac6c0(10)]>", 
    "<NSLayoutConstraint:0x1456acfd0 UIView:0x1456ac6c0.trailingMargin == UILabel:0x1456ac830'raker'.trailing>", 
    "<NSLayoutConstraint:0x1456ad020 UILabel:0x1456ac830'raker'.leading == UIView:0x1456ac6c0.leadingMargin>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1456acfd0 UIView:0x1456ac6c0.trailingMargin == UILabel:0x1456ac830'raker'.trailing> 

suy nghĩ ban đầu của tôi là phá vỡ những khó khăn này là những gì đã gây ra vấn đề thay đổi kích thước.

Cập nhật phương pháp của tế bào awakeFromNib:

override func awakeFromNib() { 
    super.awakeFromNib() 
    contentView.translatesAutoresizingMaskIntoConstraints = false 
} 

sửa các cảnh báo, nhưng vấn đề vẫn còn xảy ra.

tôi đã cố gắng tái thêm những hạn chế của riêng tôi giữa tế bào và contentView của nó, nhưng điều này không giải quyết được vấn đề này:

override func awakeFromNib() { 
    super.awakeFromNib() 
    contentView.translatesAutoresizingMaskIntoConstraints = false 

    for constraint in [ 
     contentView.leadingAnchor.constraintEqualToAnchor(leadingAnchor), 
     contentView.trailingAnchor.constraintEqualToAnchor(trailingAnchor), 
     contentView.topAnchor.constraintEqualToAnchor(topAnchor), 
     contentView.bottomAnchor.constraintEqualToAnchor(bottomAnchor)] 
    { 
     constraint.priority = 999 
     constraint.active = true 
    } 
} 

Suy nghĩ?

+0

Hai năm sau và tôi vẫn gặp phải vấn đề tương tự. Có một vài radar cho nó http://www.openradar.me/23728611; giả sử một là của bạn, mặc dù? :) – Roland

+0

Đã thêm một bản dupe: rdar: // 35717256 – Roland

Trả lời

0

Bố cục lưu lượng sẽ tính kích thước thực tế của ô sau khi thực hiện bố cục theo kích thước ước tính để xác định kích thước nào hiển thị. Sau đó, nó điều chỉnh bố cục dựa trên kích thước thực.

Tuy nhiên, khi nó hoạt hình, khi nó tính toán vị trí ban đầu cho hoạt ảnh, nó không đạt đến giai đoạn của các tế bào dequeueing và chạy bố trí tự động ở đó, vì vậy nó chỉ sử dụng kích thước ước tính.

Cách dễ nhất là cố gắng cung cấp các kích thước ước tính gần nhất hoặc nếu bạn có thể cung cấp kích thước trong đại biểu trong cuộc gọi sizeForItemAt.

Trong trường hợp của tôi, tôi đã cố gắng để animate layoutAttributes mà không cần chèn hoặc xóa các tế bào và cho rằng trường hợp cụ thể Tôi subclassed UICollectionViewFlowLayout và sau đó ghi đè phương pháp này:

override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { 
    if !context.invalidateEverything && context.invalidatedItemIndexPaths == nil && context.contentOffsetAdjustment == .zero && context.contentSizeAdjustment == .zero { 
     return 
    } 
    super.invalidateLayout(with: context) 
} 

Điều này ngăn cản tính lại bố trí các thuộc tính sử dụng kích thước ước tính khi không có gì đã thay đổi.

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