gpt4 book ai didi

ios - 使用 UICollectionViewFlowLayout/UICollectionViewLayout 子类,不会在正确的时间调用 CellForItemAtIndexPath

转载 作者:行者123 更新时间:2023-12-02 15:32:10 24 4
gpt4 key购买 nike

这个问题不是重复的,尽管我在 stavkOverflow 上看到很多类似的问题。这是我的代码的情况:

  1. CellForItemAtIndexPath - 如果我的 Collection View 位于 UIStackView 的外部,则会正确调用。仅当其位于 stackView 内部时才会出现问题

  2. 我已经从 UICollectionViewFlowLayout 正确地子类化了我的 flowLayout。

  3. CollectionView 正确返回 numberOfSections 以及每个部分中的 NumberOfItems。每个部分的项目数为 42(6 行 x 7 列)

问题如下:您可以看到它将达到不调用 CellForItemAtIndexPath 方法的程度。那里不会有细胞。然后突然间,当您滚动到某个点时,它将立即被调用,导致单元格出现。

enter image description here

有人知道错误可能是什么吗?如果 UICollectionView 未放置在 UIStackView 中,则不会发生此错误。

[编辑]

好的。我已将问题范围缩小到 UICollectionViewFlowLayout 子类。其中有一小行代码将 collectionView 的布局更改为水平。这意味着, View 上的单元格通常呈现如下:

[1][4][7]
[2][5][8]
[3][6][9]

//But the code should render it like this
[1][2][3]
[4][5][6]
[7][8][9]

我有以下代码来执行此操作(取自 KDCalendar)。这段代码工作正常,但是一旦进入 stackView,它就会看起来像上面显示的内容。在 stackView 中更改单元格顺序的方法是否不同?以下是导致问题的代码(仅在stackView内部)

override  public func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
if let attrs = super.layoutAttributesForItemAtIndexPath(indexPath) {
let attrscp = attrs.copy() as! UICollectionViewLayoutAttributes
self.applyLayoutAttributes(attrscp)
return attrscp
}
return nil
}

override public func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return super.layoutAttributesForElementsInRect(rect)?.map {
attrs in
let attrscp = attrs.copy() as! UICollectionViewLayoutAttributes
self.applyLayoutAttributes(attrscp)
return attrscp
}
}

func applyLayoutAttributes(attributes : UICollectionViewLayoutAttributes) {
if attributes.representedElementKind != nil {return}
if let collectionView = self.collectionView {
let stride = (self.scrollDirection == .Horizontal) ? collectionView.frame.size.width : collectionView.frame.size.height
let offset = CGFloat(attributes.indexPath.section) * stride
var xCellOffset : CGFloat = CGFloat(attributes.indexPath.item % 7) * self.itemSize.width
var yCellOffset : CGFloat = CGFloat(attributes.indexPath.item / 7) * self.itemSize.height
if(self.scrollDirection == .Horizontal) {
xCellOffset += offset;
} else {
yCellOffset += offset
}
attributes.frame = CGRectMake(xCellOffset, yCellOffset, self.itemSize.width, self.itemSize.height)
}
}

所以我想基本上我的问题是,什么代码是通过子类化 UICollectionViewFlowLayout 水平渲染单元格的最快最有效的方法,如上所示?我的 collectionView 将始终有 7 列。行数只能是 1、2、3 或 6。

[编辑]

我已将问题缩小到以下函数:

func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
//Inside this function, I have put the following code to test it.
print(super.layoutAttributesForElementsInRect(rect))
}

这是我得到的打印输出

  • [0] : index path: ( {length = 2, path = 0 - 0}); frame = (0 0; 59.1429 72.8333);
    • 1 : index path: ( {length = 2, path = 0 - 1}); frame = (0 73; 59.1429 72.8333);
    • [2] : index path: ( {length = 2, path = 0 - 2}); frame = (0 145.667; 59.1429 72.8333);
    • [3] : index path: ( {length = 2, path = 0 - 3}); frame = (0 218.667; 59.1429 72.8333);
    • [4] : index path: ( {length = 2, path = 0 - 4}); frame = (0 291.333; 59.1429 72.8333);
    • [5] : index path: ( {length = 2, path = 0 - 5}); frame = (0 364.333; 59.1429 72.8333);
    • [6] : index path: ( {length = 2, path = 0 - 6}); frame = (59 0; 59.1429 72.8333);
    • [7] : index path: ( {length = 2, path = 0 - 7}); frame = (59 73; 59.1429 72.8333);
    • [8] : index path: ( {length = 2, path = 0 - 8}); frame = (59 145.667; 59.1429 72.8333);
    • [9] : index path: ( {length = 2, path = 0 - 9}); frame = (59 218.667; 59.1429 72.8333);
    • [10] : index path: ( {length = 2, path = 0 - 10}); frame = (59 291.333; 59.1429 72.8333);
    • [11] : index path: ( {length = 2, path = 0 - 11}); frame = (59 364.333; 59.1429 72.8333);
    • [12] : index path: ( {length = 2, path = 0 - 12}); frame = (118.333 0; 59.1429 72.8333);
    • [13] : index path: ( {length = 2, path = 0 - 13}); frame = (118.333 73; 59.1429 72.8333);
    • [14] : index path: ( {length = 2, path = 0 - 14}); frame = (118.333 145.667; 59.1429 72.8333);
    • [15] : index path: ( {length = 2, path = 0 - 15}); frame = (118.333 218.667; 59.1429 72.8333);
    • [16] : index path: ( {length = 2, path = 0 - 16}); frame = (118.333 291.333; 59.1429 72.8333);
    • [17] : index path: ( {length = 2, path = 0 - 17}); frame = (118.333 364.333; 59.1429 72.8333);
    • [18] : index path: ( {length = 2, path = 0 - 18}); frame = (177.333 0; 59.1429 72.8333);
    • [19] : index path: ( {length = 2, path = 0 - 19}); frame = (177.333 73; 59.1429 72.8333);
    • [20] : index path: ( {length = 2, path = 0 - 20}); frame = (177.333 145.667; 59.1429 72.8333);
    • [21] : index path: ( {length = 2, path = 0 - 21}); frame = (177.333 218.667; 59.1429 72.8333);
    • [22] : index path: ( {length = 2, path = 0 - 22}); frame = (177.333 291.333; 59.1429 72.8333);
    • [23] : index path: ( {length = 2, path = 0 - 23}); frame = (177.333 364.333; 59.1429 72.8333);
    • [24] : index path: ( {length = 2, path = 0 - 24}); frame = (236.667 0; 59.1429 72.8333);
    • [25] : index path: ( {length = 2, path = 0 - 25}); frame = (236.667 73; 59.1429 72.8333);
    • [26] : index path: ( {length = 2, path = 0 - 26}); frame = (236.667 145.667; 59.1429 72.8333);
    • [27] : index path: ( {length = 2, path = 0 - 27}); frame = (236.667 218.667; 59.1429 72.8333);
    • [28] : index path: ( {length = 2, path = 0 - 28}); frame = (236.667 291.333; 59.1429 72.8333);
    • [29] : index path: ( {length = 2, path = 0 - 29}); frame = (236.667 364.333; 59.1429 72.8333);
    • [30] : index path: ( {length = 2, path = 0 - 30}); frame = (295.667 0; 59.1429 72.8333);
    • [31] : index path: ( {length = 2, path = 0 - 31}); frame = (295.667 73; 59.1429 72.8333);
    • [32] : index path: ( {length = 2, path = 0 - 32}); frame = (295.667 145.667; 59.1429 72.8333);
    • [33] : index path: ( {length = 2, path = 0 - 33}); frame = (295.667 218.667; 59.1429 72.8333);
    • [34] : index path: ( {length = 2, path = 0 - 34}); frame = (295.667 291.333; 59.1429 72.8333);
    • [35] : index path: ( {length = 2, path = 0 - 35}); frame = (295.667 364.333; 59.1429 72.8333);
    • [36] : index path: ( {length = 2, path = 0 - 36}); frame = (355 0; 59.1429 72.8333);
    • [37] : index path: ( {length = 2, path = 0 - 37}); frame = (355 73; 59.1429 72.8333);
    • [38] : index path: ( {length = 2, path = 0 - 38}); frame = (355 145.667; 59.1429 72.8333);
    • [39] : index path: ( {length = 2, path = 0 - 39}); frame = (355 218.667; 59.1429 72.8333);
    • [40] : index path: ( {length = 2, path = 0 - 40}); frame = (355 291.333; 59.1429 72.8333);
    • [41] : index path: ( {length = 2, path = 0 - 41}); frame = (355 364.333; 59.1429 72.8333);
    • [42] : index path: ( {length = 2, path = 1 - 0}); frame = (414 0; 59.1429 72.8333);
    • [43] : index path: ( {length = 2, path = 1 - 1}); frame = (414 73; 59.1429 72.8333);
    • [44] : index path: ( {length = 2, path = 1 - 2}); frame = (414 145.667; 59.1429 72.8333);
    • [45] : index path: ( {length = 2, path = 1 - 3}); frame = (414 218.667; 59.1429 72.8333);
    • [46] : index path: ( {length = 2, path = 1 - 4}); frame = (414 291.333; 59.1429 72.8333);
    • [47] : index path: ( {length = 2, path = 1 - 5}); frame = (414 364.333; 59.1429 72.8333);
    • [48] : index path: ( {length = 2, path = 1 - 6}); frame = (473 0; 59.1429 72.8333);
    • [49] : index path: ( {length = 2, path = 1 - 7}); frame = (473 73; 59.1429 72.8333);
    • [50] : index path: ( {length = 2, path = 1 - 8}); frame = (473 145.667; 59.1429 72.8333);
    • [51] : index path: ( {length = 2, path = 1 - 9}); frame = (473 218.667; 59.1429 72.8333);
    • [52] : index path: ( {length = 2, path = 1 - 10}); frame = (473 291.333; 59.1429 72.8333);
    • [53] : index path: ( {length = 2, path = 1 - 11}); frame = (473 364.333; 59.1429 72.8333);
    • [54] : index path: ( {length = 2, path = 1 - 12}); frame = (532.333 0; 59.1429 72.8333);
    • [55] : index path: ( {length = 2, path = 1 - 13}); frame = (532.333 73; 59.1429 72.8333);
    • [56] : index path: ( {length = 2, path = 1 - 14}); frame = (532.333 145.667; 59.1429 72.8333);
    • [57] : index path: ( {length = 2, path = 1 - 15}); frame = (532.333 218.667; 59.1429 72.8333);
    • [58] : index path: ( {length = 2, path = 1 - 16}); frame = (532.333 291.333; 59.1429 72.8333);
    • [59] : index path: ( {length = 2, path = 1 - 17}); frame = (532.333 364.333; 59.1429 72.8333);
    • [60] : index path: ( {length = 2, path = 1 - 18}); frame = (591.333 0; 59.1429 72.8333);
    • [61] : index path: ( {length = 2, path = 1 - 19}); frame = (591.333 73; 59.1429 72.8333);
    • [62] : index path: ( {length = 2, path = 1 - 20}); frame = (591.333 145.667; 59.1429 72.8333);
    • [63] : index path: ( {length = 2, path = 1 - 21}); frame = (591.333 218.667; 59.1429 72.8333);
    • [64] : index path: ( {length = 2, path = 1 - 22}); frame = (591.333 291.333; 59.1429 72.8333);
    • [65] : index path: ( {length = 2, path = 1 - 23}); frame = (591.333 364.333; 59.1429 72.8333);
    • [66] : index path: ( {length = 2, path = 1 - 24}); frame = (650.667 0; 59.1429 72.8333);
    • [67] : index path: ( {length = 2, path = 1 - 25}); frame = (650.667 73; 59.1429 72.8333);
    • [68] : index path: ( {length = 2, path = 1 - 26}); frame = (650.667 145.667; 59.1429 72.8333);
    • [69] : index path: ( {length = 2, path = 1 - 27}); frame = (650.667 218.667; 59.1429 72.8333);
    • [70] : index path: ( {length = 2, path = 1 - 28}); frame = (650.667 291.333; 59.1429 72.8333);
    • [71] : index path: ( {length = 2, path = 1 - 29}); frame = (650.667 364.333; 59.1429 72.8333);
    • [72] : index path: ( {length = 2, path = 1 - 30}); frame = (709.667 0; 59.1429 72.8333);
    • [73] : index path: ( {length = 2, path = 1 - 31}); frame = (709.667 73; 59.1429 72.8333);
    • [74] : index path: ( {length = 2, path = 1 - 32}); frame = (709.667 145.667; 59.1429 72.8333);
    • [75] : index path: ( {length = 2, path = 1 - 33}); frame = (709.667 218.667; 59.1429 72.8333);
    • [76] : index path: ( {length = 2, path = 1 - 34}); frame = (709.667 291.333; 59.1429 72.8333);
    • [77] : index path: ( {length = 2, path = 1 - 35}); frame = (709.667 364.333; 59.1429 72.8333);

我可以看到该函数正在询问第 0 部分的索引路径:0-00-41,这是正确的。但是,它只要求其他部分的索引路径 1-01-35。它缺少其他 6 个索引路径。当用户将缺失的单元格滚动到 View 中时,它仅显示其他 6 个路径。它不返回所有索引是否有原因?这是否是检测直肠细胞的正确方法?

最佳答案

您的 JTAppleCalendarFlowLayout 存在根本性缺陷。

UICollectionView 在内部依赖 layoutAttributesForElementsInRect() 来了解要从 layoutAttributesForItemAtIndexPath 请求哪些单元格。 由于您将矩形传递给 super 而不进行修改,因此它无法正确理解哪些单元格应该可见。

为了更好地演示该问题,我制作了保持同步的 Collection View 的第二个副本,但禁用了底部的 applyLayoutAttributes 修改。我还对出现得太晚的单元格进行了着色。

demo animation

您必须了解的部分是,在顶部 collectionView 中“太晚”出现的单元格在原始/未修改的布局中尚不可见。 Collection View 仅在认为很快需要它们时才添加它们。它没有意识到您实际上已经使它们可见。

那么......你应该如何解决它?

由于您的布局非常简单,我建议您不要使用UICollectionViewFlowLayout,因为它不是为以这种方式处理“页面”而设计的。只需子类化 UICollectionViewLayout,并使用自定义计算自行实现layoutAttributesForElementsInRect 和layoutAttributesForItemAtIndexPath 即可。

或者,如果您确实决定使用 UICollectionViewFlowLayout,则需要修改传递给 super 的矩形,以便在原始布局下,该矩形将包含在修改后的布局下可见的所有单元格。

关于ios - 使用 UICollectionViewFlowLayout/UICollectionViewLayout 子类,不会在正确的时间调用 CellForItemAtIndexPath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36412116/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com