我有一个UICollectionView的流程布局.它在大多数情况下都会像我预期的那样工作,但偶尔会有一个细胞包裹不好.例如,如果在第二行中实际尾随,则第三行的第一"列"中应该打开的单元格,并且该单元格所在的位置只有一个空白(见下图).你所能看到的这个胭脂细胞是左手边(其余部分被切断),它应该是空的.

这种情况并不总是发生;它并不总是同一排.一旦发生了,我可以向上滚动,然后再往回滚动,细胞就会自行修复.或者,当我按下单元格(通过一个按钮将我带到下一个视图)然后弹回来时,我会看到单元格处于错误的位置,然后它会跳到正确的位置.

滚动速度似乎更容易重现问题.当我慢慢滚动时,我仍然可以不时看到单元格处于错误的位置,但它会立即跳转到正确的位置.

当我添加了部分插入时,问题就开始了.以前,我让单元格几乎与集合边界齐平(很少或没有插入),但我没有注意到这个问题.但这意味着集合视图的左右两侧都是空的.Ie,无法滚动.此外,滚动条没有向右齐平.

我可以在模拟器和iPad 3上解决这个问题.

我猜问题的发生是因为左边和右边的插页.但是如果值是错误的,那么我会期望行为是一致的.我想知道这是不是苹果的问题?或者,这可能是由于插页的堆积或类似的原因.

问题和设置图解


Follow up:我已经使用Nick的this answer已经超过两年了,没有任何问题(如果人们想知道答案中是否有漏洞--我还没有找到任何漏洞).尼克,干得好.

推荐答案

UICollectionViewFlowLayout的layoutAttributesForElementsInRect实现中存在缺陷,导致它在涉及节插入的某些情况下返回单个单元格的两个属性对象.返回的属性对象中有一个无效(在集合视图边界之外),另一个有效.下面是UICollectionViewFlowLayout的子类,它通过排除集合视图边界之外的单元格来修复该问题.

// NDCollectionViewFlowLayout.h
@interface NDCollectionViewFlowLayout : UICollectionViewFlowLayout
@end

// NDCollectionViewFlowLayout.m
#import "NDCollectionViewFlowLayout.h"
@implementation NDCollectionViewFlowLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
  NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
  NSMutableArray *newAttributes = [NSMutableArray arrayWithCapacity:attributes.count];
  for (UICollectionViewLayoutAttributes *attribute in attributes) {
    if ((attribute.frame.origin.x + attribute.frame.size.width <= self.collectionViewContentSize.width) &&
        (attribute.frame.origin.y + attribute.frame.size.height <= self.collectionViewContentSize.height)) {
      [newAttributes addObject:attribute];
    }
  }
  return newAttributes;
}
@end

请参见this.

其他的答案建议从shouldInvalidateLayoutForbaysChange返回yes,但这会导致不必要的重新计算,甚至不能完全解决问题.

我的解决方案完全解决了这个问题,当苹果修复了根本原因时,应该不会造成任何问题.

Ios相关问答推荐

无法在fastlane和github操作中从react-native 应用程序构建ios

在Swift5中,将某些属性值从一个类复制到另一个类实例

不使用iOS 17修改器修改SWIFT用户界面视图

在iOS 17脉冲符号效果不起作用的情况下制作UIBarButtonItem动画(没有UIImageView)

当 .searchable 修饰符处于活动状态时,如何将变量设置为 false?

Strange UIView.animate更改UIButton标题 colored颜色 的行为

在Xcode 15中为具有@Binding的视图创建SwiftUI #预览的方法

在左侧显示多行值时会出现 SwiftUI 错误,这会 destruct 堆栈中右侧的对齐方式

Swift/iOS:泛型错误:协议需要嵌套类型V;你想添加它吗?

SwiftUI:如何为 ScrollView 制作可拉伸(灵活)的粘性标题?

使用 CIImage 支持的 UIImage 设置 UIImageView 时发生罕见的崩溃

如何在 SwiftUI 中检测 TextField 的实时变化?

无法验证客户端 3000

当键盘出现在 iOS 中时,将 UIView 上移

Xcode 10.2 无法在 iOS < 10 的模拟器上运行应用程序

应用程序不包含正确的测试版权利

UISegmentedControl 以编程方式更改段数

iPhone UITableView.如何开启音乐 App 之类的单字母字母列表?

在两个或多个 iPhone 应用程序之间共享数据

为什么我需要@1x、@2x 和@3x iOS 图像?