首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UICollectionViewLayout未按预期工作

UICollectionViewLayout未按预期工作
EN

Stack Overflow用户
提问于 2016-10-18 09:16:33
回答 1查看 1.8K关注 0票数 6

我使用xcode 8和raywenderlich.com 3跟踪了这个raywenderlich.com。

在实现了本教程中请求的所有方法之后,当我运行该应用程序时,我得到了以下错误:

‘没有UICollectionViewLayoutAttributes -layoutAttributesForItemAtIndexPath实例:{length = 2,path =0-11}’

因此,我在我的CollectionViewFlowLayout类中添加了以下方法:

代码语言:javascript
复制
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {

    return self.cache[indexPath.row]
}

这几乎是有效的,除了一些细胞正在覆盖现有的细胞时,滚动下来,然后消失。如果我向上滚动,一切都很完美。

我还不明白这段代码的全部逻辑,但我已经对它进行了多次检查和测试,我无法理解代码的哪一部分触发了这种行为。

有什么想法吗?

代码语言:javascript
复制
import UIKit

/* The heights are declared as constants outside of the class so they can be easily referenced elsewhere */
struct UltravisualLayoutConstants {
struct Cell {
    /* The height of the non-featured cell */
    static let standardHeight: CGFloat = 100
    /* The height of the first visible cell */
    static let featuredHeight: CGFloat = 280
}
}
class UltravisualLayout: UICollectionViewLayout {
// MARK: Properties and Variables

/* The amount the user needs to scroll before the featured cell changes */
let dragOffset: CGFloat = 180.0

var cache = [UICollectionViewLayoutAttributes]()

/* Returns the item index of the currently featured cell */
var featuredItemIndex: Int {
    get {
        /* Use max to make sure the featureItemIndex is never < 0 */
        return max(0, Int(collectionView!.contentOffset.y / dragOffset))
    }
}

/* Returns a value between 0 and 1 that represents how close the next cell is to becoming the featured cell */
var nextItemPercentageOffset: CGFloat {
    get {
        return (collectionView!.contentOffset.y / dragOffset) - CGFloat(featuredItemIndex)
    }
}

/* Returns the width of the collection view */
var width: CGFloat {
    get {
        return collectionView!.bounds.width
    }
}

/* Returns the height of the collection view */
var height: CGFloat {
    get {
        return collectionView!.bounds.height
    }
}

/* Returns the number of items in the collection view */
var numberOfItems: Int {
    get {
        return collectionView!.numberOfItems(inSection: 0)
    }
}

// MARK: UICollectionViewLayout

/* Return the size of all the content in the collection view */
override var collectionViewContentSize : CGSize {

    let contentHeight = (CGFloat(numberOfItems) * dragOffset) + (height - dragOffset)

    return CGSize(width: width, height: contentHeight)
}

override func prepare() {


    let standardHeight = UltravisualLayoutConstants.Cell.standardHeight

    let featuredHeight = UltravisualLayoutConstants.Cell.featuredHeight

    var frame = CGRect.zero

    var y:CGFloat = 0

    for item in 0 ... (numberOfItems - 1) {

        let indexPath = NSIndexPath(item: item, section: 0)

        let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath)

        attributes.zIndex = item

        var height = standardHeight

        if indexPath.item == featuredItemIndex {

            let yOffset = standardHeight * nextItemPercentageOffset

            y = self.collectionView!.contentOffset.y - yOffset

            height = featuredHeight


        } else if item == (featuredItemIndex + 1) && item != numberOfItems {

            let maxY = y + standardHeight

            height = standardHeight + max((featuredHeight - standardHeight) * nextItemPercentageOffset, 0)

            y = maxY - height
        }

        frame = CGRect(x: 0, y: y, width: width, height: height)

        attributes.frame = frame

        cache.append(attributes)

        y = frame.maxY
    }
}

/* Return all attributes in the cache whose frame intersects with the rect passed to the method */

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

    var layoutAttributes = [UICollectionViewLayoutAttributes]()

    for attributes in cache {

        if attributes.frame.intersects(rect) {

            layoutAttributes.append(attributes)
        }
    }

    return layoutAttributes
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {

    return self.cache[indexPath.row]
}

/* Return true so that the layout is continuously invalidated as the user scrolls */
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {

    return true
}
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-28 08:20:27

刚刚补充说,在视图控制器的super.viewDidLoad中,拥有UICollection视图,它现在正在按预期工作。

这是一个快速的修复,我相信有一种更合适的方法可以更好地解决这个问题--从IOS10中获取预取函数。

代码语言:javascript
复制
if #available(iOS 10.0, *) {
    collectionView!.prefetchingEnabled = false
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40104210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档