2015-12-02 8 views
5

Löschen Ich habe ein einfaches Projekt mit einem Storyboard nur eine einzige eine UICollectionViewController enthält, gebaut mit Xcode 7.1.1 für iOS 9,1UICollectionView Zellen Größe ändern, wenn Elemente mit 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 
     } 
    } 
} 

Wenn die Zellen aus der Sammlung Ansicht Löschen , alle übrigen Zellen animieren zu ihrer estimatedItemSize und wechseln dann wieder auf die richtige Größe.

enter image description here

Interessanterweise erzeugt diese automatische Layout-Beschränkungs Warnungen für jede Zelle, wenn die Animation stattfindet:

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> 

Mein erster Gedanke war, dass diese Einschränkungen war zu brechen, was die Redimensionierung Problem verursacht wurde.

Aktualisieren der awakeFromNib Methode der Zelle:

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

behebt die Warnungen, aber das Problem weiterhin auftritt.

Ich habe versucht, meine eigenen Zwänge zwischen der Zelle Wieder Zugabe und seine contentView, aber diese lösen das Problem nicht:

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 
    } 
} 

Gedanken?

+0

Zwei Jahre später, und ich habe immer noch das gleiche Problem. Es gibt ein paar Radar dafür http://www.openradar.me/23728611; Angenommen, du gehörst doch zu dir? :) – Roland

+0

Hinzugefügt einen Betrogenen: Rdar: // 35717256 – Roland

Antwort

0

Flow-Layout berechnet die tatsächlichen Zellengrößen nach dem Layout nach geschätzten Größen, um zu bestimmen, welche sichtbar sind. Danach passt es das Layout basierend auf realen Größen an.

Wenn es jedoch animiert wird, wenn es die Anfangsposition für die Animation berechnet, erreicht es nicht die Phase des Entfernens von Zellen und das Ausführen von Auto-Layout dort, so dass es nur geschätzte Größen verwendet.

Der einfachste Weg ist zu versuchen, die nächsten geschätzten Größen zu geben, oder wenn Sie die Größe in der Delegierten in sizeForItemAt Anruf angeben könnten.

In meinem Fall, ich habe versucht layoutAttributes ohne Einfügen oder Löschen von Zellen und für diesen speziellen Fall subclassed ich UICollectionViewFlowLayout zu animieren und dann diese Methode außer Kraft gesetzt:

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

Dies verhindert, dass das Layout neu berechnete Attribute geschätzte Größen zu verwenden, wenn nichts wurde geändert.

Verwandte Themen