Пользовательское нажатие кнопки не работает в UIView в представлении нижнего колонтитула таблицы - PullRequest
0 голосов
/ 09 апреля 2019

У меня самый странный сценарий, который я не могу исправить. У меня есть пользовательская кнопка, которую я добавляю как подпредставление к 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 голосов
/ 09 апреля 2019

Как вы заметили, кнопка не может быть нажата, потому что она отображалась за пределами рамки контейнера кнопки.

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

    }

}

Теперь размер вашего нижнего колонтитула будет корректно изменяться в зависимости от ограничений автоматического макета - поэтому, если вы добавите элементы в представление нижнего колонтитула, вам не придется явно изменять значение высоты.

0 голосов
/ 09 апреля 2019

Причина, по которой кнопка не реагировала на нажатия, заключалась в том, что кадр 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. Autolayout должен был вывести свой кадр, по крайней мере, размером его подпредставлений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...