我试图使用estimatedItemSize动态调整collectionView单元格的大小以适应内容塔的需要我遇到了一些不同设备大小的问题,特别是宽度没有调整,只是保持了界面生成器中的大小不变。
我已经在iPhone 7上完成了界面构建的工作,所以屏幕宽度是375。在我的故事板我有以下。
外部集合视图固定到具有0边距的超视图的所有4侧
w:339 h:550的outerCollectionView单元
在这个牢房里我有:
innerCollectionView固定到单元格的所有4个边(边距为0)
innerCollectionView常量w:339 h:550添加到IB中
在DataSource和Delegate类中,我在viewDidLoad函数中定义了流布局:
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
let flow = outerCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
flow.estimatedItemSize = CGSize(width: width - ((width / 18.75)), height: height / 4)
flow.minimumLineSpacing = (width / 37.5)
flow.sectionInset = UIEdgeInsets(top: (width / 37.5), left: (width / 37.5), bottom: (width / 37.5), right: (width / 37.5))
在包含“内部”集合的自定义单元格类中,我设置了一些常量约束,并定义了流布局以调整项的大小:
// This is the correct screen size
// let width = innerCollectionView.frame.size.width
let width = UIScreen.main.bounds.size.width
let flow = innerCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
flow.sectionInset = UIEdgeInsetsMake((width / 37.5), (width / 37.5), (width / 37.5), (width / 37.5))
flow.itemSize = CGSize(width: (width / 6 - (width / 37.5)), height: (width / 6 - (width / 37.5)))
flow.minimumInteritemSpacing = (width / 37.5)
flow.minimumLineSpacing = (width / 37.5)
innerCollectionHeight.constant = innerCollectionView.collectionViewLayout.collectionViewContentSize.height
innerCollectionWidth.constant = innerCollectionView.collectionViewLayout.collectionViewContentSize.width
现在,所有这些都可以正常工作了,单元格垂直调整大小,以便在iPhone7模拟器上很好地适应我的内容,显示了正确填充的单列单元格。但是当我加大一个设备的尺寸时并不能调整电池的宽度。当我使用一个更小的设备时,我会得到一大堆关于单元格宽度是如何变大的Xcode错误,因为它没有调整大小,但是没有显示任何内容。(下图)
2017-02-16 12:53:49.632 ParseStarterProject-Swift[26279:394906] The behavior of the UICollectionViewFlowLayout is not defined because:
2017-02-16 12:53:49.632 ParseStarterProject-Swift[26279:394906] the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
2017-02-16 12:53:49.632 ParseStarterProject-Swift[26279:394906] Please check the values returned by the delegate.
2017-02-16 12:53:49.633 ParseStarterProject-Swift[26279:394906] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7be38920>, and it is attached to <UICollectionView: 0x7db03600; frame = (0 0; 320 504); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7d61a550>; layer = <CALayer: 0x7be95880>; contentOffset: {0, 0}; contentSize: {320, 20}> collection view layout: <UICollectionViewFlowLayout: 0x7be38920>.
很明显我不能用
flow.itemSize =
设置外部单元格的大小,因为我需要估计的大小来调整垂直长度和拥抱内容。我就是搞不懂为什么宽度不适合屏幕大小??
大型设备-边距太大:CV width 339
iPhone7,我做的-正常边距:CV宽度339
----编辑-----
已尝试重写szeForItemAt,但没有更改。
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = self.view.frame.size.width
let height = self.view.frame.size.height
if collectionView == self.outerCollectionView {
return CGSize(width: width - 100, height: height / 4)
} else {
return CGSize(width: (width / 6 - (width / 75)), height: (width / 6 - (width / 75)))
}
}
----编辑----
我可以编辑单元格的首选项捕获。使用“压缩大小”选项作为“高度”,并设置“宽度”的“我自己的大小”(width/18.7)是宽度减去前面定义的左右插入
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let attributes = layoutAttributes.copy() as! UICollectionViewLayoutAttributes
let width = UIScreen.main.bounds.size.width
let desiredWidth = width - (width / 18.75)
//let desiredWidth = systemLayoutSizeFitting(UILayoutFittingExpandedSize).width
let desiredHeight = systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
attributes.frame.size.width = desiredWidth
attributes.frame.size.height = desiredHeight
return attributes
}
Bu这填充了如下图所示的约束,我认为这可能只是一个脚本,我运行它来填充UIViews的上角。但它也会把细胞塞得满满当当,因为它每行都会塞得更多。
屏幕更小,电池也有类似问题:
最佳答案
解决方案是实现UICollectionViewDelegateFlowLayout
并像这样调用sizeForItemAt
:
extension YourClass: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout:UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
//return size needed
return CGSize(width: (width / 6 - (width / 37.5)), height: (width / 6 - (width / 37.5)))
}
在运行时,返回的大小将是给定项大小的大小。
注意:不执行
sizeForItemAt
将不会成功