将设备旋转到横向时的UICollectionViewFlowLayout大小警告

Mik*_*son 37 objective-c ios uicollectionview uicollectionviewlayout

我们使用UICollectionView来显示覆盖整个屏幕的单元格(减去状态和导航栏).单元格大小设置为self.collectionView.bounds.size:

- (void)viewWillAppear:(BOOL)animated
{
    //
    // value isn't correct with the top bars until here
    //
    CGSize tmpSize = self.collectionView.bounds.size;
    _currentCellSize = CGSizeMake( (tmpSize.width), (tmpSize.height));
}

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout*)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    return _currentCellSize;
}
Run Code Online (Sandbox Code Playgroud)

这为每个设备设置了正确的大小.每个单元格都定义为没有插入,并且布局没有页眉或页脚.但是,当我们从纵向旋转到横向时,我们得到以下"投诉":

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)

现在我理解了这个错误,但是我们重置了单元格的大小并使用了内置旋转过渡的流程布局:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    //self.collectionView.bounds are still the last size...not the new size here
}
- (void)didRotateFromInterfaceOrientation: UIInterfaceOrientation)fromInterfaceOrientation
{
    CGSize tmpSize = self.collectionView.bounds.size;
    _currentCellSize = CGSizeMake( (tmpSize.width), (tmpSize.height));
    [self.collectionView performBatchUpdates:nil completion:nil];//this will force the redraw/size of the cells.
}
Run Code Online (Sandbox Code Playgroud)

单元格在景观中正确渲染.

似乎Flow Layout看到了旧的单元格大小(由于它太高而引起了抱怨),但确实读取/渲染了新的单元格大小didRotateFromInterfaceOrientation.

有没有办法摆脱投诉?

我们已经尝试在设备旋转转换期间找到另一个钩子,它可以访问正确的目标屏幕大小(与当前屏幕大小相比)而没有运气.调试输出显示投诉发生在willRotateToInterfaceOrientation之前但之前didRotateFromInterfaceOrientation.

我们也证实了这一点; 如果我们将单元格高度设置为小于横向屏幕高度的固定大小,则不会发生投诉.此外,从景观旋转回肖像时不会发生投诉.

一切运行正常,并正确呈现.然而,这个抱怨让我们担心.其他人有任何想法或解决方案吗?

Chr*_*kle 36

我得到了同样的警告.不满意"reloadData"方法,我发现[self.collectionView.collectionViewFlowLayout invalidateLayout] 设置集合视图的框架之前调用会使警告静音并产生预期的结果.

  • @Dejel:你会想要使用`[self.collectionView.collectionViewLayout invalidateLayout];` (8认同)

Jos*_*uce 9

不要在这个装满但尚未接受的芭比娃娃上扔另一只虾.

- (CGSize)collectionView:(UICollectionView *)collectionView 
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    [collectionView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    return CGSizeMake(100, collectionView.frame.size.height);
}
Run Code Online (Sandbox Code Playgroud)

在返回单元格大小之前设置内容插入对我来说是个窍门.

注意:

我在故事板中使用容器视图来加载UIViewController中的集合视图.我尝试在故事板中的flowLayout对象上设置它.故事板中的集合视图.并覆盖其中一个UICollectionViewDelegateFlowLayout; 虽然我不记得哪一个.我也不确定这是否适用于垂直布局.


小智 6

[UIViewController willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration]
Run Code Online (Sandbox Code Playgroud)

我打电话给,[UICollectionViewLayout invalidateLayout]似乎工作得很好.


小智 0

在调整 UICollectionView 框架大小时,我遇到了同样的问题。如果我使用 FlowLayout 上的委托方法返回单元格的大小(将根据包含的 UICollectionView 的大小进行更新),当我调整(缩小) UICollectionView 的框架大小时,我会收到错误消息,因为它在投诉之前似乎没有向代表询问更新的尺寸信息。它最终会在重绘时向委托方法询问尺寸信息,但在我分配新的框架方法时它仍然会发出警告。为了消除警告,我在将框架设置为新的较小值之前显式设置了 UICollectionViewFlowLayout 对象的 itemSize 属性。我的情况很简单,我认为我可以在此时进行 itemSize 计算(因为集合视图中的所有项目都具有相同的大小),而不是依赖于委托方法。仅在实现委托方法的同时设置 itemSize 属性并不能解决问题,因为我认为如果它检测到实现了委托方法,它会忽略 itemSize 的值(如果它知道它在那里,为什么不调用它?!)。希望这会有所帮助 - 也许您还可以在旋转之前显式设置 itemSize。