因為參加鐵人30的原因,每天都會研究一點東西寫出來但因為最近工作量比較大,所以主要會以實現功能為主,有很多地方可以做得更好,先留著以後回頭改了:D
另外也有些朋友給我留言或者寫信,可能都要等到這陣子忙完才能來回覆了。
連續三天的卡片佈局方式,這次是卡片疊加豎直滑動的應用。
Hotel Card Layout
這樣的應用應該也是常見的,卡片豎直滑動,並且會停留在頂部,而不是直接滑出畫面。
HotelCardCell
卡片樣式,左邊顯示 Hotel 的名稱,右邊顯示金額。
通過 code 做圓角,提供一個 data 屬性用來放 model, 通過 loadContent 來 render 內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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)" } } } |
HotelCardCollectionViewFlowLayout
繼承於 UICollectionViewFlowLayout
首先通過 minimumLineSpacing 讓卡部分重疊。
1 |
minimumLineSpacing = -20.0 |
我們的目標就是防止滑到最頂端的卡繼續向上移動,而當滑動 UICollectionView 的時候,都會調用到這個方法拿到新的 Attributes
1 |
func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?{} |
所以在這個方法中我們可以即時的去修正卡片的位置。
通過 max() 函數,我們確保卡片最多只能走到 collectionView!.bounds.minY + collectionView!.contentInset.top 這個位置。
然後前面通過設定 minimumLineSpacing 已經讓卡片重疊了,這裡再通過改變 zIndex 讓視覺上呈現下面的卡疊在上面的卡上的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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 } |
HomeViewController
使用起來很容易,只需要制定 UICollectionView 的 collectionViewLayout
1 |
collectionView.collectionViewLayout = HotelCardCollectionViewFlowLayout() |
Reference
- 這次的學習對象 – StickyCollectionView
- 在 Github 上有本文相关的 Source Code