Запретить родительскому UIControl отвечать на события touchDown
Я создаю многоразовую MetaControl
это состоит из нескольких субэлементов управления (см. рис.). Наследуется от UIControl
и содержит 2 простых UIButtons
и пользовательский слайдер, который я создал. CustomSlider
также наследует от UIControl
,
в MetaControl
инициализатор, я добавляю некоторые целевые действия, которые получают события от субэлементов управления, чтобы информировать MetaControl
изменений.
class MetaControl: UIControl {
public override init(frame: CGRect) {
self.slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
self.slider.addTarget(self, action: #selector(sliderTouched), for: .touchDown)
self.button1.addTarget(self, action: #selector(button1Pressed), for: .touchDown)
self.button2.addTarget(self, action: #selector(button2Pressed), for: .touchDown)
}
}
а потом я поставил селектор:
@objc private func sliderTouched() {
print("The slider was touched")
}
У меня проблема с sliderTouched()
событие. Это событие запускается дважды, когда я прикасаюсь к ползунку.
- Первый раз, кажется, отправлено с
MetaControl
сам. - Второй раз - правильное событие, передаваемое из
CustomSlider
сам.
У меня вопрос, как я могу предотвратить MetaControl
сам реагировать на события, в то же время позволяя моим CustomSlider
отправить свои действия?
Я использовал 2 способа, чтобы подтвердить, что это было MetaControl
Сам, который вызвал дополнительное событие:
Закомментировал действие кода отправки в
CustomSlider
, Даже без этой строки кода,sliderTouched()
еще называется:class CustomSlider: UIControl { var isTouched = false { didSet { //sendActions(for: .touchDown) } } }
Заменил
.touchDown
действие с.applicationReserved
, Так как я больше не использую.touchDown
,MetaControl
"s.touchDown
событие никогда не называется.class CustomSlider: UIControl { var isTouched = false { didSet { sendActions(for: .applicationReserved) } } }
Интересно, что UIButtons
не вызывайте этой же проблемы. Нажатие UIButton
не вызывает двух событий для запуска. Как я могу достичь этого же?
PS То, как я вызываю события от CustomSlider
через обычай UIPanGestureRecognizer
который встроен в CustomSlider
собственный инициализатор.
Я использовал это в качестве руководства: https://www.raywenderlich.com/82058/custom-control-tutorial-ios-swift-reusable-knob
PPS Я надеюсь, что я не пойду неправильно, включив все эти элементы управления в MetaControl
что тогда само наследует от UIControl
, MetaControl
сам никогда не реагирует на сенсорные события - только субконтроли. Я использую MetaControl
в основном в качестве контейнера для управления общим состоянием, обеспечения структуры макета и повторного использования элемента управления. В конце концов, мне нужно много из них.
1 ответ
Ответ состоял в том, чтобы убедиться, что также переопределить touchesBegan
в слайдере.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}