Как вы заметили, кнопка не может быть нажата, потому что она отображалась за пределами рамки контейнера кнопки.
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
}
}
Теперь размер вашего нижнего колонтитула будет корректно изменяться в зависимости от ограничений автоматического макета - поэтому, если вы добавите элементы в представление нижнего колонтитула, вам не придется явно изменять значение высоты.