2017-03-04 67 views
1

我對XX單元格使用UICollectionView。我如何以編程方式更改每個單元格上的XY位置?我可以改變每個細胞的大小:更改UICollectionView單元格XY位置 - swift 3

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

是否有另一個像上面這樣的功能改變XY定位?

+0

你會propably需要繼承'UICollectionViewLayout'或'UICollectionViewFlowLayout'並有實現自定義的布點。你確切的用例是什麼?也許可以通過調整佈局參數來實現?你看過[UICollectionViewFlowLayout](https://developer.apple.com/reference/uikit/uicollectionviewflowlayout)文檔嗎? – Losiowaty

+0

我已經完成了100次文檔。我對swift很陌生,因此製作任何「自定義」子類都是非常耗時的。但我願意學習,如果你能指出我正確的方向,我將非常感謝:) – fayyaz

+0

使用案例:24個圖像與空白的白色帆布/海報上的自定義位置。用戶可以改變位置,圖像等。 – fayyaz

回答

0

我希望這個例子能幫助你。讓我來解釋一下這個代碼塊。你可以考慮標準的UICollectionView和Cell設計。沒有detailView。此代碼實現將創建視差效果HeaderView。

首先

import UIKit 

class DIYLayoutAttributes: UICollectionViewLayoutAttributes { 

    var deltaY: CGFloat = 0 

    override func copy(with zone: NSZone?) -> Any { 
    let copy = super.copy(with: zone) as! DIYLayoutAttributes 
    copy.deltaY = deltaY 
    return copy 
    } 

    override func isEqual(_ object: Any?) -> Bool { 
    if let attributes = object as? DIYLayoutAttributes { 
     if attributes.deltaY == deltaY { 
     return super.isEqual(object) 
     } 
    } 
    return false 
    } 

} 

class DIYLayout: UICollectionViewFlowLayout { 
    var maximumStretchHeight: CGFloat = 0 

    override class var layoutAttributesClass : AnyClass { 
     return DIYLayoutAttributes.self 
    } 


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

    // Create layout attributes 
    let layoutAttributes = super.layoutAttributesForElements(in: rect) as! [DIYLayoutAttributes] 

    // How far user scrollview. 
    let insets = collectionView!.contentInset 
    let offset = collectionView!.contentOffset 

    let minY = -insets.top 

    // we need the calculate delta. 
    if (offset.y < minY) { 
     let deltaY = fabs(offset.y - minY) 

     // we can loop through all attributes 
     for attributes in layoutAttributes { 

     //Manipulate attributes 
     if let elementKind = attributes.representedElementKind { 
      if elementKind == UICollectionElementKindSectionHeader { 
      // create frame. 
      var frame = attributes.frame 
      frame.size.height = max(minY, headerReferenceSize.height + deltaY) 

      //We need the change origin for scrolling. 
      frame.origin.y = frame.minY - deltaY 
      attributes.frame = frame 
      attributes.deltaY = deltaY 
      } 
     } 
     } 
    } 
    return layoutAttributes 
    } 

    // Layout will scroll. 
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { 
    return true 
    } 

第二 你需要定製單元設計。

import UIKit 

class ScheduleHeaderView: UICollectionReusableView { 

    @IBOutlet fileprivate weak var backgroundImageView: UIView! 
    @IBOutlet fileprivate weak var backgroundImageViewHeightLayoutConstraint: NSLayoutConstraint! 

    @IBOutlet fileprivate weak var foregroundImageView: UIView! 
    @IBOutlet fileprivate weak var foregroundImageViewHeightLayoutConstraint: NSLayoutConstraint! 


    fileprivate var backgroundImageViewHeight: CGFloat = 0 
    fileprivate var foregroundImageViewHeight: CGFloat = 0 
    fileprivate var previousHeight: CGFloat = 0 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     backgroundImageViewHeight = backgroundImageView.bounds.height 
     foregroundImageViewHeight = foregroundImageView.bounds.height 
    } 

     override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { 
      super.apply(layoutAttributes) 
      let attributes = layoutAttributes as! DIYLayoutAttributes 
      let height = attributes.frame.height 
      if previousHeight != height { 
       backgroundImageViewHeightLayoutConstraint.constant = backgroundImageViewHeight - attributes.deltaY 
       foregroundImageViewHeightLayoutConstraint.constant = foregroundImageViewHeight + attributes.deltaY 
       previousHeight = height 
      } 
     } 

    } 

第三

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 
    let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "ScheduleHeader", for: indexPath) as! ScheduleHeaderView 
    return header 
    } 

當然,我們需要從viewDidLoad中來。

override func viewDidLoad() { 
    super.viewDidLoad() 

    //Add layout. 

    let width = collectionView!.bounds.width 
    let layout = collectionViewLayout as! DIYLayout 
    layout.headerReferenceSize = CGSize(width: width, height: 180) 
    layout.itemSize = CGSize(width: width, height: 62) 
    layout.maximumStretchHeight = width 
    } 
+0

Wow Durul,讓我試試看,幾天後回來! :-) – fayyaz

相關問題