2016-10-18 21 views
6

Tôi đi theo Custom Collection View Layout tutorial này từ raywenderlich.com sử dụng xcode 8 và nhanh chóng 3.UICollectionViewLayout không làm việc như mong đợi

Khi tôi chạy ứng dụng sau khi thực hiện tất cả các phương pháp được yêu cầu trong hướng dẫn này, tôi đã nhận lỗi sau:

'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: {length = 2, path = 0 - 11}'

Vì vậy, tôi đã thêm các phương pháp sau vào lớp CollectionViewFlowLayout tôi:

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

    return self.cache[indexPath.row] 
} 

này hầu như làm việc trừ som rằng các ô e đang phủ các ô hiện có khi cuộn xuống và sau đó biến mất. Nếu tôi cuộn lên, mọi thứ sẽ hoạt động hoàn hảo.

Tôi không hiểu logic đầy đủ của mã này nhưng tôi đã xem xét và kiểm tra nó nhiều lần và tôi không thể hiểu phần nào của mã đang kích hoạt hành vi này.

Bất kỳ ý tưởng nào?

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 
} 
} 

Trả lời

0

Chỉ cần thêm rằng trong super.viewDidLoad của trình điều khiển chế độ xem sở hữu chế độ xem UICollection và hiện đang hoạt động như mong đợi.

Đây là một bản sửa lỗi nhanh và tôi tin rằng có một cách thích hợp hơn để khắc phục điều này quản lý tốt hơn các chức năng tìm nạp trước từ IOS10.

if #available(iOS 10.0, *) { 
    collectionView!.prefetchingEnabled = false 
} 
Các vấn đề liên quan