如何处理TableViewCell中的自定义UIView按钮动作?

时间:2019-01-07 14:34:17

标签: ios swift uitableview

如何处理TableViewCell中的自定义UIView按钮操作?

我有带有XIB的自定义UIView,我将它添加到了UIViewControler中实现的TableView中。对于每个单元格,我在tableView函数-cellForRowAt中添加我的自定义UIView。一切看起来都很好,但是我无法处理该单元格添加的自定义UIView中的按钮操作。有人可以帮我怎么做吗?

编辑:

我的自定义UIView具有自己的XIB。

protocol TicketButtonDelegate {
    func starButtonAction(_: UIButton)
}

class TicketView: UIView {

    @IBOutlet var ticketContentView : UIView!
    var delegate: TicketButtonDelegate!

    @IBOutlet weak var starButton : UIButton!

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    private func commonInit() {

        Bundle.main.loadNibNamed("TicketView", owner: self, options: nil)
        addSubview(ticketContentView)

        starButton.addTarget(self, action: #selector(starButtonAction(_:)), for: .touchUpInside)

        ticketContentView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 132)
    }

    @objc func starButtonAction(_ sender: UIButton) {
        delegate.starButtonAction(sender)
    }
}

我的UIViewController。

class MhdDashboardBottom: UIViewController, TicketButtonDelegate {
    @IBOutlet weak var mhdTicketsTable: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        mhdTicketsTable.delegate = self
        mhdTicketsTable.dataSource = self
        mhdTicketsTable.register(UINib(nibName: "MhdTicketTableCell", bundle: nil), forCellReuseIdentifier: "MhdTicketCell")
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "MhdTicketCell"

        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? MhdTicketTableCell else {
            fatalError("The dequeued cell is not an instance of MhdTicketTableCell")
        }

        let ticket = tickets[indexPath.row]
        let ticketCell = TicketView()
        ticketCell.delegate = self
        ticketCell.tag = 700
        var viewExists = false
        for view in cell.contentCellView.subviews {
            if view.tag == ticketCell.tag {
                viewExists = true
                break
            }
        }
        if viewExists == false {
            cell.contentCellView.addSubview(ticketCell)
        }
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 132
    }

    func starButtonAction(_: UIButton) {
        print("Works?")
    }
}

我的MhdTicketTableCell(UITableViewCell)

class MhdTicketTableCell: UITableViewCell {
    @IBOutlet weak var contentCellView: UIView!
}

2 个答案:

答案 0 :(得分:1)

它不是协议使用回调闭包,而是避免了视图层次结构数学,标记和协议声明:

  • 在视图中删除协议

    protocol TicketButtonDelegate {
       func starButtonAction(_: UIButton)
    } 
    

  • var delegate: TicketButtonDelegate!替换为weak var callback: (() -> Void)?

  • 替换

    @objc func starButtonAction(_ sender: UIButton) {
        delegate.starButtonAction(sender)
    }
    

    使用

    @objc func starButtonAction(_ sender: UIButton) {
        callback?()
    }
    
  • 在控制器中删除

    func starButtonAction(_: UIButton) {
        print("Works?")
    }
    

  • 替换

    ticketCell.delegate = self
    

    使用

    ticketCell.callback = {
       print("Works?", indexPath)
    }
    

捕获了索引路径甚至ticket

答案 1 :(得分:0)

经过漫长的研究,我提出了解决方案。

在我的TicketView中,我必须添加此功能才能将触摸事件传递到子视图中。

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    for subview in subviews {
        if !subview.isHidden && subview.isUserInteractionEnabled && subview.point(inside: convert(point, to: subview), with: event) {
            return true
        }
    }
    return false
}

此后,我删除了委托实现,而我刚刚添加了

ticketCell.starButton.addTarget(self, action: #selector(starButtonAction(_:)), for: .touchUpInside)

进入UIViewControlers cellForRow函数,然后添加objc函数

@objc func starButtonAction(_ sender: UIButton) {
    print("Works?")
}

非常感谢this回答的问题。