美文网首页
UITableView--点击选择与展开

UITableView--点击选择与展开

作者: JQWONG | 来源:发表于2019-11-12 18:49 被阅读0次

本文是一个实例讲解
很多App都会有一页让用户选择喜好,会涉及喜好分类以及选择
本文将讲解大致的实现过程

每一个Cell前面会有一个Checkbox,通过Checkbox来表示是否选择
每个分类的Section可以收起或展开


最终效果

实现一个带Checkbox的Cell

iOS的基础控件中并没有Checkbox这个组件,我们可以用UIButton来代替,因为UIButton都有状态属性,可以满足我们的要求
Cell的构造很简单,只需要一个UILable与一个UIButton
因为用户是点击整个Cell可以进行选择,所以应该禁止UIButton的交互,否则会有拦截点击事件的问题

private let topicLabel: UILabel = {
        let label = UILabel()
        return label
    }()

private let checkBoxButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(named: "lightCheckboxOff"), for: .normal)
        button.setImage(UIImage(named: "lightCheckboxOn"), for: .selected)
        button.isUserInteractionEnabled = false
        return button
    }()

与其说点击改变UIButton的状态,倒不如说是改变Cell的状态,只不过UIButton将改变的结果展示出来,我们需要开放一个是否选择的属性给外层调用,在点击Cell的时候改变checkBoxButton的状态

public var isChecked: Bool = false {
        didSet {
            checkBoxButton.isSelected = isChecked
        }
    }

在UITableViewDelegate的didSelectRowAt方法里面进行选择的操作,点击Cell的时候获取对应indexPath的数据,是否展开的值取反,然后设置Cell的isChecked属性改变checkBoxButton与文字颜色,最后刷新

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = TableViewCell_checkbox()
        let model = models[indexPath.section]
        let row = model.rows[indexPath.row]
        row.isChecked = !row.isChecked
        cell.isChecked = row.isChecked
        tableView.performBatchUpdates({
            tableView.reloadRows(at: [indexPath], with: .automatic)
        }, completion: nil)
    }

到此为止,一个带checkBox可以点击选择的Cell已经完成了
下面我们来做点击header收起展开的功能

实现一个Header

这里的header只有一个ULabel与一个箭头,section展开与收起箭头会改变方向

private lazy var sectionLabel: UILabel = {
        let label = UILabel()
        return label
    }()

    private lazy var arrowIcon: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "iconRightArrowGrey")
        imageView.contentMode = .scaleAspectFit
        imageView.transform = CGAffineTransform(rotationAngle: .pi / 2)
        return imageView
    }()

同样的,header需要有一个是否展开的属性开控制箭头的方向

public var isExpand: Bool = true {
        didSet {
            arrowIcon.transform = isExpand ? CGAffineTransform(rotationAngle: 3 * .pi / 2) : CGAffineTransform(rotationAngle: .pi / 2)
        }
    }

header是一个UIView,我们在整个View上添加一个手势,然后调用代理方法,让外层的ViewController实现代理方法

// 定义协议
protocol ExpandHeaderDelegate: class {
    func didTapSection(header: ExpandHeader, section: Int)
}

@objc func tapHeader(gestureRecognizer: UITapGestureRecognizer) {
        guard let header = gestureRecognizer.view as? ExpandHeader else {
            return
        }
        delegate?.didTapSection(header: self, section: header.section)
    }

设置header

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ExpandHeader") as? ExpandHeader else { return nil }
        let model = models[section]
        header.setHeaderTitle(model.section)
        header.section = section
        header.delegate = self
        header.isExpand = model.expand
        return header
    }

代理方法实现思路与Cell点击类似,就是获取数据改变状态然后刷新

func didTapSection(header: ExpandHeader, section: Int) {
        models[section].expand = !models[section].expand
        tableView.reloadSections([section], with: .automatic)
    }

这里是整个项目的Demo
支持原创,版权所有

相关文章

网友评论

      本文标题:UITableView--点击选择与展开

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