2016-09-09 6 views
1

UICollectionViewLayout을 구현할 때. 레이아웃을 무효화하고 prepare()에서 속성을 다시 작성하면 셀은 재사용 할 때 이전 레이어를 렌더링합니다. 또는 collectionView가 잘못 렌더링됩니다. iOS10에서만 발생합니다. 이전 버전에서는 올바르게 렌더링되었습니다. 크기가 일정 할 때 발생하지 않습니다.동적으로 크기를 조정하는 UICollectionViewLayout iOS10의 ReRenders 레이어

그리고 collectionView의 prepareForReuse 또는 layoutSubviews에서이를 지울 수 없습니다. 여기

class PortfolioDisplayFlowLayout: UICollectionViewLayout { 

    var cache = [UICollectionViewLayoutAttributes]() 

    // amount the user need to scroll before the feature cell changes 
    let dragOffset:CGFloat = 180 

    // return item index of currently featured cell 
    var featuredItemIndex:Int { 
     get { 
      return max(0, Int(collectionView!.contentOffset.y/dragOffset)) 
     } 
    } 

    var headerItemIndex:Int { 
     get { 
      return 0 
     } 
    } 

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

    // math helpers 
    var numberOfItems:Int { 
     get { 
      return collectionView!.numberOfItems(inSection: 0) 
     } 
    } 

    var width : CGFloat { 
     get { 
      return collectionView!.bounds.width 
     } 
    } 

    var height : CGFloat { 
     get { 
      return collectionView!.bounds.height 
     } 
    } 


    // MARK: UICollectionViewLayout 
    override func prepare() { 
     cache.removeAll(keepingCapacity: false) 
     invalidateLayout() 
     let standardHeight:CGFloat = 100 
     let featuredHeight:CGFloat = 280 

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

     for item in 0..<numberOfItems { 
      let indexPath = IndexPath(item:item, section:0) 
      let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) 

      attributes.zIndex = item 
      var height = standardHeight 

      if indexPath.item == featuredItemIndex { 
       let yOffset = standardHeight * nextItemPercentageOffset 
       y = collectionView!.contentOffset.y - yOffset 
       height = featuredHeight 
      } else if indexPath.item == (featuredItemIndex + 1) && indexPath.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 
     } 
    } 

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { 
     return true 
    } 

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { 
     return cache[indexPath.row] 
    } 

    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 var collectionViewContentSize: CGSize { 
     let contentHeight = (CGFloat(numberOfItems) * dragOffset) + (height - dragOffset) 
     return CGSize(width: width, height: contentHeight) 
    } 
} 

는 여기에 애플의 최신 WWDC와 답을 찾을 아이폰 OS 9 Here is a screen shot of the collectionView in iOS 9

답변

3

에서 collectionView의 스크린 샷이 Here is a screen shot of the collectionView in iOS 10

아이폰 OS (10)의 collectionView의 스크린 샷이다. 스크롤하는 동안 셀 크기를 변경하려면 collectionView의 새 속성 isPrefetchingEnabled을 false로 설정해야합니다. 기본적으로 true로 설정됩니다.

if #available(iOS 10.0, *) { 
    collectionView?.isPrefetchingEnabled = false 
}