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

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


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范例

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 每个UIView有一个伙伴称为layer,一个CALayer。UIView实际上并没有把自己画到屏幕上;它绘制本身...
    shenzhenboy阅读 3,155评论 0 17
  • 所有示例代码均可以在 Animations-Demo 下载到 上节提到 UIView 上所有动画归根结底都是发生在...
    smalldu阅读 4,840评论 0 18
  • http://blog.csdn.net/guojin08/article/details/60773120 屏幕...
    pony23阅读 914评论 0 2
  • 首先感谢小易童鞋,这里自己也整理下这些容易忘记的代码 设置导航栏的背景颜色用barTintColor self.n...
    HT_Jonson阅读 954评论 0 51
  • 一、如何提高一个应用程序的性能?1、使用ARC减少内存失误,dealloc需要重写并对属性置nil。2、重用。3、...
    金歌漫舞阅读 997评论 2 6