美文网首页Mac·iOS开发
iOS Swift 卡片列表堆叠效果实现

iOS Swift 卡片列表堆叠效果实现

作者: jzhang | 来源:发表于2020-01-15 16:28 被阅读0次

    之前看到一个多张银行卡卡片叠加、点击动态展开的效果,感觉很不错,抽空实现了一下。


    Screen Shot 2020-04-20 at 9.54.34 AM.jpg 未命名-min 2.gif

    思路:
    用 UITableView 实现,一张卡片就是一个 Cell,展开一张卡片就是 update 这个 Cell 的高度。

    Cell

    cell xib

    绘制圆角、阴影

        @IBOutlet var cardView: UIView!
        @IBOutlet var cardImg: UIImageView!
    
        override func awakeFromNib() {
            super.awakeFromNib()
            // Initialization code
            let radius: CGFloat = 15
            cardView.layer.cornerRadius = radius
            cardView.layer.shadowColor = UIColor.black.cgColor
            cardView.layer.shadowOpacity = 0.5
            cardView.layer.shadowOffset = CGSize(width: 0.5, height: 0.5)
            cardView.layer.shadowRadius = radius
            cardImg.layer.cornerRadius = radius
            cardImg.clipsToBounds = true
            
            backgroundColor = .clear
            contentView.backgroundColor = .clear
        }
    

    从上图可以看到,我这里使用xib画的cell,由于卡片比例是固定的,所以cardView加比例约束,防止卡片变形。进一步根据比例和屏幕宽度,计算出卡片展开时cell的高度openHeight(卡片被遮挡时的高度固定54):

    let openHeight: CGFloat = (UIScreen.main.bounds.size.width - 30) * (593 / 939) + 25
    let closeHeight: CGFloat = 54
    

    CardView 左、上、右相对superView都设置了约束,因为要实现效果是上一张卡被下一张卡遮挡,所以底部不需要加约束。

    显示时,上面所有的cell都是close的,被点击才会更新高度(展开或收起)。当点击第二个cell时,关闭前一个cell,打开后一个cell,保证一次只打开一张卡。最后一个cell是固定open的,点击也不会改变高度。

    现在运行效果是左边这样的,好像是有点样子了,但是是上面的卡遮住了下面的卡。上拉一下,让部分卡片到屏幕外,松手之后又变成了右边这样。这是因为随着cell的复用,界面上cell的之间的层级是变化的,导致卡的层级也发生了变化。


    image.png QQ20200115-154642@2x.jpg

    那如果设置cell的clipsToBounds,让超出部分不显示呢?
    答案是不行:


    QQ20200115-160527@2x.jpg

    可以看到,红框是实际cell的位置,要让cell2卡片挡住cell1卡片,cell1的卡片必须超出cell1的范围,穿过cell2卡片下方。所以clipsToBounds这个方法行不通

    解决办法

    这时候需要用到layer的zPosition属性:
    这个属性的作用是设置显示的优先级,数字越高,就越会显示在最前面(但是不会影响响应链的优先级)
    layer.zPosition探究

    具体到这里,就是保证在下面的cell.layer.zPosition的值永远比上面的大就行了。比如说这里界面上,从上到下的layer.zPosition的值分别设置为是1,2,3,这样就可以保证下张卡一直显示在上一张卡上面。

    最近用Xcode11运行demo,发现在iOS13的模拟器上面执行动画时,cell上面透明部分会变成不透明,折腾了我好久,最后发现其实只是iOS13模拟器的问题,我用真机就完全没问题,fxxk。

    总体思路就是这些,下面附上demo。

    ZJTableViewManager中的ZJTableViewDemo的BasicExample的UpdateHeight范例

    相关文章

      网友评论

        本文标题:iOS Swift 卡片列表堆叠效果实现

        本文链接:https://www.haomeiwen.com/subject/soxtzctx.html