因為參加鐵人30的原因,每天都會研究一點東西寫出來但因為最近工作量比較大,所以主要會以實現功能為主,有很多地方可以做得更好,先留著以後回頭改了:D
另外也有些朋友給我留言或者寫信,可能都要等到這陣子忙完才能來回覆了。
連續三天的卡片佈局方式,這次是卡片疊加豎直滑動的應用。
這樣的應用應該也是常見的,卡片豎直滑動,並且會停留在頂部,而不是直接滑出畫面。
卡片樣式,左邊顯示 Hotel 的名稱,右邊顯示金額。
通過 code 做圓角,提供一個 data 屬性用來放 model, 通過 loadContent 來 render 內容。
class HotelCardCell: UICollectionViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var priceLabel: UILabel!
var data:Any?
override func awakeFromNib() {
super.awakeFromNib()
layer.cornerRadius = 12
layer.masksToBounds = true
}
func loadContent() {
if let model = data as? HotelModel {
backgroundColor = model.color
nameLabel.text = model.name
priceLabel.text = "$ \(model.price)"
}
}
}
繼承於 UICollectionViewFlowLayout
首先通過 minimumLineSpacing 讓卡部分重疊。
minimumLineSpacing = -20.0
我們的目標就是防止滑到最頂端的卡繼續向上移動,而當滑動 UICollectionView 的時候,都會調用到這個方法拿到新的 Attributes
func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?{}
所以在這個方法中我們可以即時的去修正卡片的位置。
通過 max() 函數,我們確保卡片最多只能走到 collectionView!.bounds.minY + collectionView!.contentInset.top 這個位置。
然後前面通過設定 minimumLineSpacing 已經讓卡片重疊了,這裡再通過改變 zIndex 讓視覺上呈現下面的卡疊在上面的卡上的效果。
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
if super.layoutAttributesForElements(in: rect) == nil { return nil }
var attributes = [UICollectionViewLayoutAttributes]()
for attribute in super.layoutAttributesForElements(in: rect)! {
let minY = collectionView!.bounds.minY + collectionView!.contentInset.top
let maxY = attribute.frame.origin.y
var newOrigin = CGPoint(x: attribute.frame.origin.x, y: max(minY, maxY))
attribute.frame = CGRect(origin: newOrigin, size: attribute.frame.size)
attribute.zIndex = attribute.indexPath.row
attributes.append(attribute)
}
return attributes
}
使用起來很容易,只需要制定 UICollectionView 的 collectionViewLayout
collectionView.collectionViewLayout = HotelCardCollectionViewFlowLayout()