1

在我的应用程序中,我有一个全屏分页集合视图,每个单元格也需要全屏,因此集合视图布局的项目大小需要具有相同的大小作为视图控制器视图的边界大小。要做到这一点,在viewDidLayoutSubviews我只是设置项目大小,它按预期工作。当我显示此屏幕时,viewDidLayoutSubviews被调用3次,并且iPhone 7每次视图的边界大小为375.0 x 667.0。单元格大小与预期相同。更改流布局的项目后单元格大小不更新大小

但是,当使用3D Touch偷看和弹出来呈现此屏幕时,单元格的大小不像预期的那样大,无论是在偷看还是弹出时。 viewDidLayoutSubviews被称为4倍,这些边界尺寸:
--- PEEK触发---
375.0 X 569.524495677234
375.0 X 569.524495677234
375.0 X 720.821325648415
---弹出触发---
375.0 X 667.0

查看时,集合视图是“全屏”,如预期的那样,高度为721,单元格的期望宽度为375,但单元格高度为569时应为721.弹出时,预期集合视图高度变为667,但单元格高度仍然为569.

设置itemSize后,我试过拨打collectionView.layoutIfNeeded(),但结果是一样的。为什么收集视图没有在这里更新单元大小?

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    print("\(view.bounds.width) x \(view.bounds.height)") 

    let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)) 
    let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout 

    if flowLayout.itemSize != boundsSize { 
     flowLayout.itemSize = boundsSize 

     collectionView.layoutIfNeeded() //this doens't help 
    } 
} 
+0

尝试用这种'collectionView.collectionViewLayout.invalidateLayout()'也许可以帮助你 –

回答

0

尝试通过flowLayout.invalidateLayout()

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    print("\(view.bounds.width) x \(view.bounds.height)") 

    let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)) 
    let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout 

    if flowLayout.itemSize != boundsSize { 
     flowLayout.itemSize = boundsSize 

     debugPrint("Called") 
     flowLayout.invalidateLayout() 
    } 
} 

希望更换collectionView.layoutIfNeeded()这有助于

+0

'的invalidateLayout()'没有做的伎俩,它给出了相同的结果 – Joey

+0

@Joey你确定你的代码进入if?把一个debugPrint放在那里,检查 –

+0

是的,确实是 – Joey

0

您可以viewDidLayoutSubviews一起使用collectionView(_:layout:sizeForItemAt:)

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    print("\(view.bounds.width) x \(view.bounds.height)") 

    let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)) 

    if !boundsSize.equalTo(self. collectionViewItemSize) { 
     collectionView.invalidateLayout() 
    } 
} 

var collectionViewItemSize:CGSize = .zero 

func collectionView(_ collectionView: UICollectionView, 
        layout collectionViewLayout: UICollectionViewLayout, 
        sizeForItemAt indexPath: IndexPath) -> CGSize { 
    self.collectionViewItemSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)); 
    return self.collectiViewItemSize; 
} 
+0

这给出了相同的结果。所以它首先重复调用'viewDidLayoutSubviews'然后调用'sizeForItemAt'并返回预期的大小。然后,布局再次以相同的尺寸被调用,它被无效并且再次重复调用项目的大小(如果我取出检查以确定实际尺寸已经改变),那么布局被称为第三次和第四次,但是它不是无效的它似乎是因为它不会再次调用'sizeForItemAt'。 – Joey

+0

这不是问题,即使你完全比较它不能按预期工作。它会触发'invalidateLayout()',但不会为第三个和第四个布局事件调用'sizeForItemAt'。 – Joey

+0

@Joey:奇怪。调用invalidateLayout后立即调用setLayout。这应该肯定会触发sizeForItemAt方法。 –

相关问题