• tableview折叠动效


    缘起于看见书旗小说的列表有点击折叠的动效,觉得十分炫酷。想了三分钟,不知道怎么写。晚上百度了下,知道了大致流程,于是自己实现了下,发现不少坑,于是写下这篇博文

    实现原理:

    1 tableview cell高度自适应

    2 点击cell时,控制cell对应的数据源显示,更新约束后,tableView reloadData

    贴下核心代码:

    class CellMdl:NSObject {
        var title:String?
        var img:UIImage?
        var detail:String?
    }
    
    class FoldCell:UITableViewCell {
        
        var title:UILabel!
        var detail:UILabel!
        var imgView:UIImageView!
        var indicator:UIImageView!
        
        var mdl:CellMdl!
        
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            addViews()
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func addViews() {
    
        }
        
        override func layoutSubviews() {
            title.snp.makeConstraints { (make) in
                make.top.left.equalTo(self)
                make.height.equalTo(44)
                make.right.equalTo(indicator.snp.left)
            }
            indicator.snp.makeConstraints { (make) in
                make.centerY.equalTo(title)
                make.right.equalTo(self)
            }
            imgView.snp.makeConstraints { (make) in
                make.top.equalTo(title.snp.bottom)
                make.left.right.equalTo(self)
            }
            detail.snp.makeConstraints { (make) in
                make.top.equalTo(imgView.snp.bottom)
                make.left.right.bottom.equalTo(self)
            }
        }
    
        
        func showIndicatorAni(back:Bool,blk:(()->Void)?) {
            let rotate = !back ? CGAffineTransform(rotationAngle: .pi) : .identity
            UIView.animate(withDuration: 0.3, animations: {
                self.indicator.transform = rotate
            }) { (finish) in
                self.detail.text = !back ? self.mdl.detail : nil
                self.imgView.image = !back ? self.mdl.img : nil
    //            self.layoutIfNeeded()
                if blk != nil {
                    blk!()
                }
            }
        }
        
        // 设置数据源
        func setMdl(cellMdl:CellMdl) {
            mdl = cellMdl
            title.text = cellMdl.title
    //        detail.text = cellMdl.detail
    //        imgView.image = cellMdl.img
        }
    }

    这里对应cell声明一个专属cell的model,为cell提供数据

    实现autolayout的关键步骤是

      1.setModel时,仅将显示的头部视图赋值,未赋值视图应没内容自适应后不会显示,将传入的model用变量存下来(后续使用)

      2.点击动画,代码请细看showIndicatorAni函数

        这里有两参数,第一个back参数:是否折叠,第二个是个blk,方便外部进行操作。

        如果不折叠,即显示全部内容,将model的数据赋值给需要显示的视图;如果折叠,不需要显示全部内容,将不需显示的视图内容清空。

        动画完且数据设置完全后,更新约束self layoutIfNeed后将动作传出

    然后是外部tableView点击的具体实现

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if previousCell != nil {
                previousCell?.showIndicatorAni(back: true,blk: nil)
            }
            
            if let foldcell = tableView.cellForRow(at: indexPath) as? FoldCell {
                weak var weakSelf = self
                foldcell.showIndicatorAni(back: false,blk: {
                    weakSelf?.tableView.reloadData()
                })
                previousCell = foldcell
            }
        }

     这里设置个变量previousCell标识前一个选择的cell。为什么写这个变量?选择的cell动画后,前一个cell的动画要还原,并且显示的视图要隐藏,要隐藏,要隐藏!!!

    然后新选择的cell.showIndicator,回调中刷新tableview

    顺带提一下tableview设置的关键点

      1.cell自适应设置姿势

       tableView.estimatedHeight = 100

       tableView.rowHeight = UITableviewAutomaticDimension

      2.cell单选

       tableView.allowMutableSelection = false

    效果图贴一张

  • 相关阅读:
    private
    接口
    抽象类的认识
    静态导入和类中的代码块
    instanceof 与 应用类型强转
    重写的理解
    继承初体验
    赶紧收藏!春招Java面经总结,拿大厂Offer的必备复习资料!
    react native 升级到0.31.0的相关问题 mac xcode开发环境
    c# 线程池多任务处理并返回值
  • 原文地址:https://www.cnblogs.com/xiaoerheiwatu/p/9637913.html
Copyright © 2020-2023  润新知