UICollectionViewCell布局问题iOS9

UICollectionViewCell布局问题iOS9,ios,uicollectionview,uicollectionviewcell,ios9,xcode7,Ios,Uicollectionview,Uicollectionviewcell,Ios9,Xcode7,自从我迁移到新的iOS9和Xcode 7之后,我偶然发现我的应用程序中的UICollectionView出现了一个问题 显然,UICollectionView似乎没有正确地更新UICollectionViewCell布局和约束,直到它被重用 图片胜于文字——这是第一次看到UIViewController时的样子: 但是,这不是正确的布局,当我水平向左滑动UICollectionView时,很容易得到新出现单元格的正确布局: 当我向后滑动时,那些不正确的旧电池现在被重新使用,看起来很好 现在,

自从我迁移到新的iOS9和Xcode 7之后,我偶然发现我的应用程序中的
UICollectionView
出现了一个问题

显然,
UICollectionView
似乎没有正确地更新
UICollectionViewCell
布局和约束,直到它被重用

图片胜于文字——这是第一次看到
UIViewController
时的样子:

但是,这不是正确的布局,当我水平向左滑动
UICollectionView
时,很容易得到新出现单元格的正确布局:

当我向后滑动时,那些不正确的旧电池现在被重新使用,看起来很好

现在,正如在升级到iOS9和Xcode 7之前一样,我想要的效果是,单元格即使在第一次出现时也有正确的布局

为方便起见,以下是有关如何设置
UICollectionView
的更多详细信息,以及XIB中的约束:

在代码中,它是相当标准的:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell : MatchmakersCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCell", forIndexPath: indexPath) as! MatchmakersCollectionViewCell

    cell.imageView.backgroundColor = UIColor.lightGrayColor()
    cell.bottomName.text = "StackOverflow"

    return cell
}

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

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}
每次我更新数据源(self.matchmakers),我都会调用
self.collectionView.reloadData()

我注意到的最后一件事非常奇怪,当使用Xcode调试调试视图层次结构时,
UICollectionViewCell
从未正确显示子视图,只是给了我一个默认的
UIView

我很肯定这是一个iOS9错误。我没有在故事板的
UICollectionView
中设置
UICollectionViewCell
UI和约束,而是创建了自己的XIB。然后添加到
UIViewController

self.collectionView.registerNib(UINib(nibName: "MatchmakersCollectionViewCell", bundle: NSBundle.mainBundle()), forCellWithReuseIdentifier: "CollectionCell")

现在它工作得很好。

我在iOS9中也有同样的错误。我希望将中心x和中心y图像添加到UICollectionView单元格。它不起作用,但现在我在故事板中添加了
Align Top
Align Leading
,然后在中添加了outlets
NSLayoutConstraint


(UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath
。我正在根据分辨率更改
NSLayoutConstraint

我在iOS9中也有同样的错误。也许您已经发现在重新加载集合视图之后一切都正常了。所以我的解决方案是:为iOS9设置一个计时器来重新加载单元格

if #available(iOS 9, *) {
   self.refreshTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("refreshDataTimer"), userInfo: nil, repeats: true)
}
并重新加载它们:

func refreshDataTimer(){

    self.collectionView?.reloadData()

}
尽管这个解决方案有点愚蠢,但它只在几行代码中起作用

也可以重新加载每个单元格:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

     .... 


    self.collectionView?.reloadItemsAtIndexPaths([indexPath])
    return cell
}
但这是低效的

要解决此问题:

  • 使用Nib(.xib)文件创建自定义UICollectionViewCell

  • 在自定义UICollectionViewCell中,重写didMoveToSuperView()方法来添加此项

    self.setNeedLayout()

    self.layoutifneed()

  • 3.在UIViewControllerviewDidLoad()方法中

    self.collectionView.registerNib(UINib(nibName:“yourNibName”,bundle:nil),forCellWithReuseIdentifier:“Cell”)

    --------更新20150923

    只需第2步,重写didMoveToSuperView方法即可添加

    self.setNeedLayout()

    self.layoutifneed()

    在自定义UICollectionViewCell类中


    谢谢@macayer

    我不必为我的手机创建我自己的XIB,只要我有我的自定义手机并将其链接到我的故事板,我就在(MyCustomCollectionViewCell.m)中添加了这些行:


    我有一部分的问题,OP描述

    在调试时,我注意到了最后一件非常奇怪的事情 使用Xcode调试视图层次结构,UICollectionViewCell永远不会 正确显示了子视图,并在中为我提供了默认的UIView 代替他们

    我花了好长时间把头撞在墙上,想弄清楚到底发生了什么事,但建议的答案都没有起作用。最后,我删除了单元格XIB中的所有约束并重新添加它们,解决了问题。我想约束一定是在某个时候损坏了


    希望它能帮助一些人。

    以下是在Xcode 7中解决此问题所需的合适的Swift 2.0代码。请注意,正确的代码是“setNeedsLayout”,而不是如上所述的“SetNeedLayout”。确保在UICollectionViewCell文件中调用它

     override func didMoveToSuperview() {
                self.setNeedsLayout()
                self.layoutIfNeeded()
            }
    

    在我的例子中,禁用.xib文件中的大小类起到了作用。

    在自定义项类中调用
    setNeedsLayout
    layoutIfNeeded
    方法在iOS 9.0公开发行版中为我起到了作用。我想知道这在效率方面是怎样的。。。
    viewdiload
    部分以及单独的
    Nib
    文件不是必需的。步骤1和3不是必需的。步骤2正是您需要的。为什么此解决方案作为ReloadItemsAndExpaths工作方法将调用cellForRowAtcellForRowAt,然后再次执行方法ReloadItemsAndExpaths,所以我想知道此解决方案工作的原因??有点讨厌。。。在最好的情况下,UI出现的延迟是不必要的,在最坏的情况下,计时器假定视图加载完成(可能仍然发生)。
     override func didMoveToSuperview() {
                self.setNeedsLayout()
                self.layoutIfNeeded()
            }