iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 16
0

https://ithelp.ithome.com.tw/upload/images/20180104/20107329oyxDtMu2kj.png
因為參加鐵人30的原因,每天都會研究一點東西寫出來但因為最近工作量比較大,所以主要會以實現功能為主,有很多地方可以做得更好,先留著以後回頭改了:D

另外也有些朋友給我留言或者寫信,可能都要等到這陣子忙完才能來回覆了。

連續三天的卡片佈局方式,這次是卡片疊加豎直滑動的應用。


Hotel Card Layout

Hotel Card Layout

這樣的應用應該也是常見的,卡片豎直滑動,並且會停留在頂部,而不是直接滑出畫面。


HotelCardCell

卡片樣式,左邊顯示 Hotel 的名稱,右邊顯示金額。
https://ithelp.ithome.com.tw/upload/images/20180104/201073295P7gNriqpl.png
通過 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)"
        }
    }

}

HotelCardCollectionViewFlowLayout

繼承於 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
}

HomeViewController

使用起來很容易,只需要制定 UICollectionView 的 collectionViewLayout

collectionView.collectionViewLayout = HotelCardCollectionViewFlowLayout()

Reference


上一篇
Flat Card Layout
下一篇
BankCoins - 讓錢幣飛一會
系列文
iOS Swift x Layout x Animation x Transition30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言