2017-03-04 70 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

相关问题