「SwiftUI」UITableViewCell左滑删除并保持圆角样式

569 阅读2分钟

UITableViewCell左滑删除调用系统删除样式,并实现Cell圆角样式

前言:通常UI设计为了美观会将列表中子模块设为圆角,并且有些列表需要实现左滑删除功能,但在使用系统UITableView删除功能时经常会出现Cell会自动变成直角,无任何圆角,影响美观

实现思路

通过Lookin查看,在Cell的delete模式下会比正常展示情况下多出一个父视图"_UITableViewCellSwipeContainerView",在父视图下包含着正常展示的Cell和删除视图"UISwipeActionPullView",所以使用layoutSubviews()方法来监控是否出现了"_UITableViewCellSwipeContainerView"父视图,当父视图出现,则进行修改Cell样式

正常展示页面结构:
在这里插入图片描述右滑删除时页面结构:
在这里插入图片描述

代码部分

UITableView部分

myTableView = UITableView(frame: .zero, style: .grouped)
myTableView.backgroundColor = UIColor.design(.design_F7F7F7)
myTableView.showsVerticalScrollIndicator = false
myTableView.separatorStyle = .none
myTableView.delegate = self
myTableView.dataSource = self

myTableView.register(UserCenterProductCell.self, forCellReuseIdentifier: NSStringFromClass(UserCenterProductCell.self))


extension ViewController: UITableViewDelegate,
                          UITableViewDataSource {

func numberOfSections(in tableView: UITableView) -> Int {
        return orderList.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(UserCenterProductCell.self), for: indexPath) as! UserCenterProductCell
        cell.updateCellWithModel(model: orderList[indexPath.row])
        cell.clickLearnMoreBtnAction = { [self] in
            let vc = HomeProductDetailViewController(model: orderList[indexPath.row])
            vc.hidesBottomBarWhenPushed = true
            
            self.navigationController?.pushViewController(vc, animated: true)
        }
        cell.selectionStyle = .none
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == orderList.count - 1 {
            return 120.fit()
            
        } else {
            return 132.fit()
        }
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    	/// 点击删除按钮后续操作
        if editingStyle == .delete {
            print("实现删除Cell操作")
        }
    }
    
    func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "删除"
    }
    
    /// 重点: 如果这个方法不加圆角在左滑的时候没有任何问题,但delete模式消失时容易出现Cell直角样式
    func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {
        if let indexPath = indexPath, let cell = tableView.cellForRow(at: indexPath) {
            cell.layer.cornerRadius = 16.fit()
            cell.layer.masksToBounds = true
        }
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView()
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 5.fit()
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 5.fit()
    }
}

UITableViewCell部分

class UserCenterProductCell: UITableViewCell {
    private var titleLabel: UILabel!
    private var dateLabel: UILabel!
    private var rateLabel: UILabel!
    private var rateUnitLabel: UILabel!
    private var stateLabel: UILabel!
    private var LearnMoreButton: UIButton!
   
    /// 外部可调用
    var clickLearnMoreBtnAction: (() -> Void)?

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        initView()
        setupLayout()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /// 核心代码!
    override func layoutSubviews() {
        super.layoutSubviews()
        /// 查找承载侧滑的父视图
        if let superView = self.superview, NSStringFromClass(superView.classForCoder) == "_UITableViewCellSwipeContainerView" {
        	/// 修改Cell圆角样式
            let maskPath = UIBezierPath(roundedRect: superView.bounds, cornerRadius: 16.fit())
            let maskLayer = CAShapeLayer()
            maskLayer.frame = superView.bounds
            maskLayer.path = maskPath.cgPath
            superView.layer.mask = maskLayer
            /// 查找侧滑删除摁钮视图
            if let subView = superView.subviews.first, NSStringFromClass(subView.classForCoder) == "UISwipeActionPullView" {
            	/// 修改侧滑视图背景色和摁钮背景色
                subView.backgroundColor = UIColor.design(.design_FF5050)
                let btn = subView.subviews.last
                btn?.backgroundColor = UIColor.design(.design_FF5050)
            }
        }
    }
    
    private func initView() {
        self.backgroundColor = UIColor.design(.design_FFFFFF)
        self.layer.cornerRadius = 16.fit()
        self.clipsToBounds = true
       
        titleLabel = UILabel.label("", textColor: UIColor.design(.design_24292B), font: UIFont.font(of: 18.fit(), weight: .medium))
        
        dateLabel = UILabel.label("", textColor: UIColor.design(.design_9DA2A5), font: UIFont.font(of: 12.fit(), weight: .regular))
        
        rateLabel = UILabel.label("", textColor: UIColor.design(.design_D81E06), font: UIFont.font(of: 30.fit(), weight: .bold))
        
        rateUnitLabel = UILabel.label("%", textColor: UIColor.design(.design_D81E06), font: UIFont.font(of: 12.fit(), weight: .medium))
        
        stateLabel = UILabel.label("", textColor: UIColor.design(.design_FF453A), font: UIFont.font(of: 14.fit(), weight: .medium))
        
        LearnMoreButton = UIButton(type: .custom)
        LearnMoreButton.setTitle("", for: .normal)
        LearnMoreButton.setTitle("", for: .highlighted)
        LearnMoreButton.setTitleColor(UIColor.design(.design_FFFFFF), for: .normal)
        LearnMoreButton.titleLabel?.font = UIFont.font(of: 14.fit(), weight: .regular)
        LearnMoreButton.layer.cornerRadius = 16.fit()
        LearnMoreButton.layer.masksToBounds = true
        LearnMoreButton.backgroundColor = UIColor.design(.design_FF8000)
        
        LearnMoreButton.addTarget(self, action: #selector(clickLearnMoreButton), for: .touchUpInside)
       
        self.contentView.addSubview(titleLabel)
        self.contentView.addSubview(dateLabel)
        self.contentView.addSubview(rateLabel)
        self.contentView.addSubview(rateUnitLabel)
        self.contentView.addSubview(stateLabel)
        self.contentView.addSubview(LearnMoreButton)
        
    }
    
    private func setupLayout() {        
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(12.fit())
            make.left.equalTo(16.fit())
        }
        
        dateLabel.snp.makeConstraints { make in
            make.bottom.equalTo(-12.fit())
            make.left.equalTo(titleLabel)
        }
        
        rateLabel.snp.makeConstraints { make in
            make.bottom.equalTo(dateLabel.snp.top)
            make.left.equalTo(titleLabel)
            make.height.equalTo(30.fit())
        }
        
        rateUnitLabel.snp.makeConstraints { make in
            make.left.equalTo(rateLabel.snp.right)
            make.bottom.equalTo(rateLabel.snp.bottom)
            make.width.equalTo(12.fit())
        }
        
        stateLabel.snp.makeConstraints { make in
            make.top.equalTo(12.fit())
            make.right.equalTo(-16.fit())
        }
        
        LearnMoreButton.snp.makeConstraints { make in
            make.bottom.equalTo(-12.fit())
            make.right.equalTo(-16.fit())
            make.size.equalTo(CGSize(width: 84.fit(), height: 32.fit()))
        }
    }
    
    @objc
    private func clickLearnMoreButton() {
    	/// Cell摁钮点击回调方法
        self.clickLearnMoreBtnAction?()
    }
    
    func updateCellWithModel(model: productModel) {
       	/// 更新Cell数据
    }
    
    func updateCellState(state: ZUArticleListFromType) {
       /// Cell功能代码
    }
}

页面展示效果

在这里插入图片描述
在这里插入图片描述