更改UICollectionView单元格XY位置 - swift 3
问题描述:
我对XX单元格使用UICollectionView。我如何以编程方式更改每个单元格上的XY位置?我可以改变每个细胞的大小:更改UICollectionView单元格XY位置 - swift 3
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
是否有另一个像上面这样的功能改变XY定位?
答
我希望这个例子能帮助你。让我来解释一下这个代码块。你可以考虑标准的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
你会propably需要继承'UICollectionViewLayout'或'UICollectionViewFlowLayout'并有实现自定义的布点。你确切的用例是什么?也许可以通过调整布局参数来实现?你看过[UICollectionViewFlowLayout](https://developer.apple.com/reference/uikit/uicollectionviewflowlayout)文档吗? – Losiowaty
我已经完成了100次文档。我对swift很陌生,因此制作任何“自定义”子类都是非常耗时的。但我愿意学习,如果你能指出我正确的方向,我将非常感谢:) – fayyaz
使用案例:24个图像与空白的白色帆布/海报上的自定义位置。用户可以改变位置,图像等。 – fayyaz