自定义按钮点击在表页脚视图的UIView中不起作用

时间:2019-04-09 12:38:46

标签: ios swift uitableview

我有无法解决的最特殊情况。我有一个自定义按钮,作为子视图添加到UIView中。然后,我将UIView添加到表视图的tableFooterView中,但无法检测到按钮点击。这是代码:

public func configureMyButton() {
        let button = CustomButton("My title")
        button.addTarget(self, action: #selector(self.buttonAction), for: .touchUpInside)
        button.isUserInteractionEnabled = true
        let buttonContainer = UIView()
        buttonContainer.addSubview(button)
        buttonContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-16-[button]", options: [], metrics: [:], views: ["button":button]))
        buttonContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[button]-8-|", options: [], metrics: [:], views: ["button":button]))
        self.tableView.tableFooterView = buttonContainer
    } 

@objc func buttonAction(sender: UIButton!) {
    print("Button tapped")
}

现在,如果我更改此内容:

self.view.addSubview(buttonContainer)

按钮点击起作用。这使我相信tableFooterView上有一些东西会阻止水龙头工作,但我不确定是什么可能。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

按钮不响应点击的原因是因为buttonContainers框架完全错误。因此,尽管在屏幕上看起来像是所有东西,但框架实际上不存在,因此按钮没有响应

public func configureMyButton() {
    let button = CustomButton("My title")
    button.addTarget(self, action: #selector(self.buttonAction), for: .touchUpInside)
    button.isUserInteractionEnabled = true
    let buttonContainer = UIView()
    buttonContainer.addSubview(button)
    buttonContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-16-[button]", options: [], metrics: [:], views: ["button":button]))
    buttonContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[button]-8-|", options: [], metrics: [:], views: ["button":button]))
    buttonContainer.layoutIfNeeded()
    buttonContainer.frame = CGRect(x: 0, y: 0, width: self.tableView.frame.size.height, height: button.frame.size.height + 16)
    self.tableView.tableFooterView = buttonContainer
}

我对解决方案不太满意。我认为我不必摆弄buttonContainer框架。自动布局应将其框架推算为至少是其子视图的大小。

答案 1 :(得分:0)

如您所述,无法轻按按钮,因为它显示在按钮容器框架的外部

UITableView处理其页眉和页脚视图的布局,因此对它们使用自动布局需要额外的步骤。

不要在viewDidLoad()中添加页脚视图。而是像这样覆盖viewDidLayoutSubviews()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // manipulating the tableFooterView will trigger viewDidLayoutSubviews()
    // so only call this if we haven't added the footer view yet
    if tableView.tableFooterView == nil {
        configureMyButton()
        tableView.layoutTableFooterView()
    }
}

更改您的configureMyButton()功能,如下所示:

public func configureMyButton() {

    // I don't have your CustomButton() func...
    //let button = CustomButton("My title")

    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle("My Title", for: .normal)
    button.backgroundColor = .blue

    button.addTarget(self, action: #selector(self.buttonAction), for: .touchUpInside)
    button.isUserInteractionEnabled = true

    let buttonContainer = UIView()

    // set background to red so we can see it - remove after testing
    buttonContainer.backgroundColor = .red

    buttonContainer.addSubview(button)

    buttonContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-16-[button]|", options: [], metrics: [:], views: ["button":button]))
    buttonContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[button]-8-|", options: [], metrics: [:], views: ["button":button]))

    self.tableView.tableFooterView = buttonContainer
}

然后添加此扩展名:

extension UITableView {

    func layoutTableHeaderView() {

        guard let tempView = self.tableHeaderView else { return }
        tempView.translatesAutoresizingMaskIntoConstraints = false

        let width = tempView.bounds.size.width;

        let temporaryWidthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "[tempView(width)]", options: NSLayoutConstraint.FormatOptions(rawValue: UInt(0)), metrics: ["width": width], views: ["tempView": tempView])

        tempView.addConstraints(temporaryWidthConstraints)

        tempView.setNeedsLayout()
        tempView.layoutIfNeeded()

        let tempSize = tempView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
        let height = tempSize.height
        var frame = tempView.frame

        frame.size.height = height
        tempView.frame = frame

        self.tableHeaderView = tempView

        tempView.removeConstraints(temporaryWidthConstraints)
        tempView.translatesAutoresizingMaskIntoConstraints = true

    }

    func layoutTableFooterView() {

        guard let tempView = self.tableFooterView else { return }
        tempView.translatesAutoresizingMaskIntoConstraints = false

        let width = tempView.bounds.size.width;

        let temporaryWidthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "[tempView(width)]", options: NSLayoutConstraint.FormatOptions(rawValue: UInt(0)), metrics: ["width": width], views: ["tempView": tempView])

        tempView.addConstraints(temporaryWidthConstraints)

        tempView.setNeedsLayout()
        tempView.layoutIfNeeded()

        let tempSize = tempView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
        let height = tempSize.height
        var frame = tempView.frame

        frame.size.height = height
        tempView.frame = frame

        self.tableFooterView = tempView

        tempView.removeConstraints(temporaryWidthConstraints)
        tempView.translatesAutoresizingMaskIntoConstraints = true

    }

}

现在,页脚视图将根据自动布局约束正确调整大小-因此,如果将元素添加到页脚视图中,则无需显式更改高度值。