Прежде всего: я настоятельно рекомендую добавить фрагменты кода вместо скриншота в ваши вопросы.
Вам нужно передать Selector
для параметра действия в UITapGestureRecognizer
вместо () -> ()
closure:
extension UIView {
func onClick(target: Any, _ selector: Selector) {
isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: target, action: selector)
addGestureRecognizer(tap)
}
}
Кроме того, имейте в виду, что на данный момент вы должны установить соответствующий target
для экземпляра tap
, что означает, что он не self
в расширении UIView
(как реализовано в вашем коде); Вместо этого вы должны передать его в качестве аргумента методу onClick
.
Использование:
В вашем ViewController:
likesImg.onClick(target: self, #selector(likesImgClicked))
@objc private func likesImgClicked() {
print(#function)
}
Когда вы говорите likesImg.onClick(target: self
: self
здесь означает сам ViewController, а не расширение UIView
, это правильная цель, потому что likesImgClicked
реализован в ViewController, но не в расширении UIView
.
UPDATE:
Если вы настаиваете на подходе к закрытию, вы можете воспользоваться следующим решением:
Реализуйте расширение UIView как:
extension UIView {
private struct OnClickHolder {
static var _closure:()->() = {}
}
private var onClickClosure: () -> () {
get { return OnClickHolder._closure }
set { OnClickHolder._closure = newValue }
}
func onClick(target: Any, _ selector: Selector) {
isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: selector)
addGestureRecognizer(tap)
}
func onClick(closure: @escaping ()->()) {
self.onClickClosure = closure
isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(onClickAction))
addGestureRecognizer(tap)
}
@objc private func onClickAction() {
onClickClosure()
}
}
Использование:
В вашем ViewController:
likesImg.onClick {
print("Hello!!")
}
ВАЖНО:
Благодарю @ Josh Caswell за следующее примечание:
Обратите внимание, что приватная структура дает вам одно хранилище для
вся программа . Если вы попытаетесь установить обработчик для более чем одного представления,
второе заменит первое.