我有无法解决的最特殊情况。我有一个自定义按钮,作为子视图添加到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
上有一些东西会阻止水龙头工作,但我不确定是什么可能。有什么想法吗?
答案 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
}
}
现在,页脚视图将根据自动布局约束正确调整大小-因此,如果将元素添加到页脚视图中,则无需显式更改高度值。