当单元格全屏时,为什么UICollectionView会记录错误?

Wes*_*Wes 31 objective-c ios uicollectionview ios7

我有一个UICollectionViewController使用UICollectionViewFlowLayoutitemSize的大小的地方UICollectionView.基本上,这是单元格的线条布局,其中每个单元格是全屏的并且水平滚动.

在我的UICollectionViewFlowLayout子类中,我已覆盖prepareLayout如下:

- (void)prepareLayout {
    self.itemSize = self.collectionView.frame.size;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.collectionView.pagingEnabled = YES;
    self.minimumLineSpacing = 0.0;
    self.minimumInteritemSpacing = 0.0;
    self.sectionInset = UIEdgeInsetsZero;
    self.footerReferenceSize = CGSizeZero;
    self.headerReferenceSize = CGSizeZero;
}
Run Code Online (Sandbox Code Playgroud)

UICollectionViewController是非常基本的一个部分返回10项.我在GitHub中包含了一个示例项目以获取更多详细信息.

一切似乎都正确设置.它在模拟器和设备上看起来正确但是,当显示集合视图时,控制台上会记录一个错误:

the behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less that the height of the UICollectionView minus the section insets top and bottom values.
Run Code Online (Sandbox Code Playgroud)

另请注意,我的示例中的集合视图控制器位于导航控制器中,虽然在示例中看起来并不是特别必要,但在我的实际案例中,我需要导航控制器中的集合视图.

Wes*_*Wes 70

有一个属性UIViewController- automaticallyAdjustsScrollViewInsets- 默认为YES.这意味着当a 在其视图层次结构中UIViewController具有a UIScrollView时 - 该属性也是如此UICollectionViewController- contentInset该滚动视图的属性会自动调整以考虑状态栏,导航栏和工具栏或标签栏所消耗的屏幕区域.

该属性的文档说明:

automaticallyAdjustsScrollViewInsets

指定视图控制器是否应自动调整其滚动视图插入.

@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets

讨论

默认值为YES,允许视图控制器调整其滚动视图插入以响应状态栏,导航栏和工具栏或标签栏消耗的屏幕区域.如果要自行管理滚动视图插入调整,则设置为NO,例如视图层次结构中有多个滚动视图时.

解决的办法是设置automaticallyAdjustsScrollViewInsetsNO某处你的UICollectionViewController子类,如viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.automaticallyAdjustsScrollViewInsets = NO;
}
Run Code Online (Sandbox Code Playgroud)

在GitHub上放了一个示例项目来说明这个问题和解决方案.有两个分支:with_errorfixed_error.这是GitHub上的变化差异.

  • 如果可以的话,我已经两次"升级"了.另外,请注意您可以在Interface Builder中更改`automaticAdjustsScrollViewInsets`. (6认同)
  • 我的集合视图是表格视图单元格的子视图之一,此解决方案不适用于我的情况. (6认同)

Leg*_*tik 15

iOS 11 更新: automaticallyAdjustsScrollViewInsets在 iOS 11.0 中已弃用。

Apple 建议改用UIScrollViewcontentInsetAdjustmentBehavior方法。我将此值设置为.never并且错误消失了。您也可以在 Interface Builder 中设置此属性。


Tam*_*gel 6

我只是在3倍屏幕(即iPhone 6 Plus)上出现了这个问题。事实证明,自动布局引擎并不真正喜欢无限的浮点值(例如.33333333),所以我的解决方法是floor返回sizeForItemAt:indexPath:

return CGSize(width: preferredWidth, height: floor(preferredHeight))
Run Code Online (Sandbox Code Playgroud)


Stu*_*ner 6

我在将设备从纵向旋转到横向,再旋转回纵向时遇到了这个问题。您希望collectionView在设备旋转时和调用 super 之前使 的布局无效,如下所示:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    // Causes collection view cells to be resized upon orientation change.
    // Important that this is called *before* call to super in order to prevent error from being logged to console.
    [self.collectionView.collectionViewLayout invalidateLayout];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    //...
}
Run Code Online (Sandbox Code Playgroud)


小智 5

这种方式对我来说非常有效!

我只是从视图的高度中减去顶部和底部的插图,如该错误中所述。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width , height: view.frame.height - (view.safeAreaInsets.top + view.safeAreaInsets.bottom))
}
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助!


Ire*_*Dev 5

如果你在scrollView中有collectionView,只需将.invalidateLayout方法放在viewDidLayoutSubviews中,如下所示:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        collectionView.collectionViewLayout.invalidateLayout()
    }
Run Code Online (Sandbox Code Playgroud)

我发现 viewWillTransitionToSize 内的 .invalidateLayout 方法在某些情况下不会更改方向更改时的集合视图边界。


Sof*_*ner 5

对我有用的修复。

collectionViewLayout.estimatedItemSize = .zero

或者通过IB进行:

Estimated Size: None

如果您在 IB 中创建集合视图,则Estimated Size属性 ( estimatedItemSize) 将设置为Auto。文档说这是.zero默认的,但事实并非如此。