RxSwift之订阅UITableViewCell里的按钮点击事件

一、前言

  • 我们知道,通过订阅 tableView 的 itemSelected 或 modelSelected 这两个 Rx 扩展方法,可以对单元格的点击事件进行响应,并执行相关的业务代码。
  • 但有时候并不需要整个 cell 都能进行点击响应,可能是点击单元格内的按钮时才触发相关的操作。

二、效果展示

  • 点击单元格右侧的按钮后,会弹出显示该单元格的内容以及索引值;
  • 而点击单元格其他位置,不触发任何操作。

在这里插入图片描述

三、示例

  • MyTableCell.swift(自定义单元格类)
    • 注意 prepareForReuse() 方法里的 disposeBag = DisposeBag();
    • 每次 prepareForReuse() 方法执行时都会初始化一个新的 disposeBag,这是因为 cell 是可以复用的,这样当 cell 每次重用的时候,便会自动释放之前的 disposeBag,从而保证 cell 被重用的时候不会被多次订阅,避免错误发生。
class MyTableCell: UITableViewCell {
    
    
     
    var button:UIButton!
    var disposeBag = DisposeBag()
     
    // 单元格重用时调用
    override func prepareForReuse() {
    
    
        super.prepareForReuse()
        disposeBag = DisposeBag()
    }
     
    // 初始化
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    
    
        super.init(style: style, reuseIdentifier: reuseIdentifier)
         
        // 添加按钮
        button = UIButton(frame:CGRect(x:0, y:0, width:40, height:25))
        button.setTitle("点击", for:.normal) 
        button.backgroundColor = UIColor.orange
        button.layer.cornerRadius = 5
        button.titleLabel?.font = UIFont.systemFont(ofSize: 13)
        self.addSubview(button)
    }
     
    // 布局
    override func layoutSubviews() {
    
    
        super.layoutSubviews()
        button.center = CGPoint(x: bounds.size.width - 35, y: bounds.midY)
    }
 
    required init?(coder aDecoder: NSCoder) {
    
    
        fatalError("init(coder:) has not been implemented")
    }
}
  • ViewController.swift(主视图控制器):
var tableView:UITableView!
let disposeBag = DisposeBag()

// 创建表格视图
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//创建一个重用的单元格
self.tableView!.register(MyTableCell.self, forCellReuseIdentifier: "Cell")
// 单元格无法选中
self.tableView.allowsSelection = false
self.view.addSubview(self.tableView!)
 
// 初始化数据
let items = Observable.just([
    "文本输入框的用法",
    "开关按钮的用法",
    "进度条的用法",
    "文本标签的用法",
    ])
 
// 设置单元格数据(其实就是对 cellForRowAt 的封装)
items
    .bind(to: tableView.rx.items) {
    
     (tableView, row, element) in
        // 初始化cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
            as! MyTableCell
        cell.textLabel?.text = "\(element)"
         
        // cell中按钮点击事件订阅
        cell.button.rx.tap.asDriver()
            .drive(onNext: {
    
     [weak self] in
                self?.showAlert(title: "\(row)", message: element)
            }).disposed(by: cell.disposeBag)
         
        return cell
    }
    .disposed(by: disposeBag)

// 显示弹出框信息
func showAlert(title: String, message: String) {
    
    
	let alert = UIAlertController(title: title, message: message,
                                  preferredStyle: .alert)
	alert.addAction(UIAlertAction(title: "确定", style: .cancel))
	self.present(alert, animated: true)
}

Guess you like

Origin blog.csdn.net/Forever_wj/article/details/121276930