Различное поведение между addTarget и addGestureRecognizer - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть функция, которая создает кнопку с функцией выбора в качестве цели.Адрес кнопки передается в handleSelectPhoto.

lazy var image1Button = createButton(selector: #selector(handleSelectPhoto))
func createButton(selector: Selector) -> UIButton {
    let button = UIButton(type: .system)
    button.addTarget(self, action: selector, for: .touchUpInside)
    return button
}
@objc func handleSelectPhoto(button: UIButton) {
    // Do something with button, this works
}

Теперь я пытаюсь изменить класс вышеупомянутого с UIButton на UIImageView следующим образом:

lazy var image1Button = createButton(selector: #selector(handleSelectPhoto))
func createButton(selector: Selector) -> UIImageView {
    let view = UIImageView()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: selector))
    view.isUserInteractionEnabled = true
    return view
}
@objc func handleSelectPhoto(button: UIImageView) {
    // HERE, button does not get passed
}

С учетом вышеуказанных изменений в handleSelectPhoto экземпляр кнопки неверен.Я не могу прочитать его как тип UIImageView.

Если я добавлю функцию выбора с использованием addGestureRecognizer, будет ли она вести себя иначе, чем добавление функции выбора с использованием addTarget, с точки зрения того, как функция выбора выполняется с параметрами?Может быть, я не понимаю, как работает эта селекторная функция ...

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Вы должны указать при настройке выбора, что ваша функция будет принимать параметр, добавив : в конце имени метода.

lazy var image1Button = createButton(selector: #selector(handleSelectPhoto:))

UIKit автоматически поймет, что методы селекторапараметр будет иметь тип UITapGestureRecognizer.Теперь перепишите нижеприведенный метод, как этот, и вам будет хорошо.

@objc func handleSelectPhoto(gesture: UITapGestureRecognizer) {
        if let buttonImageView = gesture.view as? UIImageView {
            //Here you can make changes in imageview what ever you want.
        }
}
0 голосов
/ 26 февраля 2019

Добавление цели к чему-то вроде UIGestureRecognizer или UIButton передает только один параметр выбранной функции.Этот параметр зависит от типа, к которому вы собираетесь добавить цель.

В вашем случае первый фрагмент кода работает, потому что вы добавляете target к UIButton, поэтому вы выбралиФункция получает этот экземпляр UIButton.

Во втором сценарии вы добавляете target к UITapGestureRecognizer, поэтому переданный экземпляр будет именно таким распознавателем жестов, который не может относится к типу UIImageView.

Таким образом, отличие от целевого параметра в перспективе между UIGestureRecognizer и UIButton не имеет значения.Они оба передают свои экземпляры выбранной функции.

С точки зрения подкласса UIView есть разница, что UIGestureRecognizer не является подклассом UIView, а UIButton.Вот почему вы можете просто использовать переданный экземпляр UIButton в своем первом фрагменте.Во втором фрагменте вам нужно использовать свойство view из UIGestureRecognizer.

guard let imageView = gestureRecognizer.view as? UIImageView else { return }

Помимо вашего фактического вопроса, важно уточнить, как правильно писать #selector s. Вы уже делаете это правильно. Никаких изменений не требуется.Некоторые могут сказать, что вам нужно добавить (_:) или : к вашему селектору, например так: #selector(handleSelectPhoto(_:)), но это не так.В общем случае эти специальные символы нужно добавлять только при выборе метода, у которого есть метод перегрузки с другим количеством параметров, но с тем же базовым именем.

...