警告:UICollectionViewFlowLayout缓存了索引路径'abc'的帧不匹配

Dhr*_*oel 27 ios uicollectionview uicollectionviewlayout swift

这是导致警告的代码:

private override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
    let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
    let distance = CGRectGetMidX(attributes!.frame) - self.midX;
    var transform = CATransform3DIdentity;
    transform = CATransform3DTranslate(transform, -distance, 0, -self.width);
    attributes!.transform3D = CATransform3DIdentity;
    return attributes
}
Run Code Online (Sandbox Code Playgroud)

控制台还打印:

这可能是因为流布局"xyz"正在修改UICollectionViewFlowLayout返回的属性而不复制它们.

我该如何修复此警告?

mat*_*att 41

这可能是因为流布局"xyz"正在修改UICollectionViewFlowLayout返回的属性而不复制它们

当然,这就是你正在做的事情:

private override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
    let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
    let distance = CGRectGetMidX(attributes!.frame) - self.midX;
    var transform = CATransform3DIdentity;
    transform = CATransform3DTranslate(transform, -distance, 0, -self.width);
    attributes!.transform3D = CATransform3DIdentity;
    return attributes
}
Run Code Online (Sandbox Code Playgroud)

我希望如果你只是说:

let attributes = 
    super.layoutAttributesForItemAtIndexPath(indexPath).copy() 
    as! UICollectionViewLayoutAttributes
Run Code Online (Sandbox Code Playgroud)

或类似的,问题将消失.


Geo*_*iev 41

除了上面的好答案.

我知道示例代码是用swift编写的,但我认为拥有Objective-C版本会很有帮助.

对于Objective-C,这将不起作用,因为复制功能只执行浅拷贝.你必须这样做:

NSArray * original   = [super layoutAttributesForElementsInRect:rect];
NSArray * attributes = [[NSArray alloc] initWithArray:original copyItems:YES];
Run Code Online (Sandbox Code Playgroud)

我添加了一个临时变量以便于阅读.


JAL*_*JAL 19

覆盖时我遇到了这个问题layoutAttributesForElementsInRect.迭代遍历super.layoutAttributesForElementsInRect(rect)数组中的每个元素并调用副本对我来说不起作用,所以我最终回到基础类并使用NSArray's copyItems:

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    // unwrap super's attributes
    guard let superArray = super.layoutAttributesForElementsInRect(rect) else { return nil }

    // copy items
    guard let attributes = NSArray(array: superArray, copyItems: true) as? [UICollectionViewLayoutAttributes] else { return nil }

    // modify attributes

    return attributes
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您发布此信息,即使有另一个答案。我正在遍历数组中的每个元素并进行复制。也没有为我工作。所以感谢您发布此解决方案。 (2认同)

Jov*_*vic 7

这不是原始问题的答案,但可以帮助layoutAttributesForElements(在rect:CGRect中)(Swift 3.0):

let safeAttributes = super.layoutAttributesForElements(in: rect)?.map { $0.copy() as! UICollectionViewLayoutAttributes }
safeAttributes?.forEach { /* do something with attributes*/ }
Run Code Online (Sandbox Code Playgroud)


Aym*_*him 6

添加到@Georgi答案

<NSCopying> 必须符合并添加复制邮件调用 layoutAttributesForItemAtIndexPath

UICollectionViewLayoutAttributes* attributes = [[super layoutAttributesForItemAtIndexPath:indexPath] copy];
Run Code Online (Sandbox Code Playgroud)