Как передать сенсорное событие для просмотра, когда userInteractionEnabled = ДА?
У меня есть следующие настройки.
+- XXXCustomControl : UIControl -------+
| A |
| +- ContentView -------------------+|
| | ||
| | B ||
| | ||
| +---------------------------------+|
+--------------------------------------+
XXXCustomControl, который является подклассом UIControl. Он содержит одно подпредставление с именем contentView типа UIView с размером, меньшим, чем область Control. Это представление имеет .userInteractionEnabled = YES
;
Мне нужно, чтобы это свойство было установлено в YES, потому что горизонтальные прокрутки время от времени помещаются внутрь, и их нужно прокручивать. Если суперпредставление (в нашем случае представление контента не позволяет взаимодействовать с пользователем, оно наследуется у подпредставлений.) Но в то же время этот XXXCustomControl
должен быть применим, когда он не содержит прокрутки в своем представлении контента не только в области А, но и в области Б.
Так что у меня здесь "конфликт интересов", потому что я либо
1) установите представление контента на userInteractionEnabled = NO
, тогда я могу нажать на пустой элемент управления в области просмотра контента как в A, так и в B, но скролл-обзоры, которые я здесь поместу, не будут прокручиваться..
2) установите для представления содержимого значение userInteractionEnabled = YES
но затем, если userInteractionEnabled = YES
управления пуст, я могу только коснуться области A, чтобы вызвать событие касания.
Одна идея, которая пришла мне в голову, заключается в том, что я по умолчанию устанавливаю для свойства значение NO, а при заполнении contentView задаю для него значение yes. когда я очищаю contentView, я возвращаю свойству значение no. По сути, я хочу, чтобы для этого параметра всегда было установлено значение yes, а когда оно пустое, принудительно заставляет contentView передавать событие touchUpInside до своего суперпредставления.
Это возможно?
Ответы
Ответ 1
Вы можете попробовать переопределить метод pointInside:withEvent:
во внутреннем представлении. Это позволит вам возвращать NO, когда вы хотите перенаправить касания в супервизор:
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if( /* You have content, and you want to receive touches */){
return YES;
}else{
return NO;
}
}
Ответ 2
Вы можете подклассифицировать свое подвью и реализовать
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (!touchedContent) {
[[self nextResponder] touchesBegan:touches withEvent:event];
} else {
[super touchesBegan:touches withEvent:event];
}
}
Ответ 3
Вы можете использовать другой UIView для "скрытия" подвью.
* Подробности: этот UIView является подчиненным братом. он имеет тот же размер и положение вашего подсмотра с цветом фона четкого цвета.
* Объясните: новый UIView примет прикосновение и автоматически передаст его в супервизор.
Таким образом, не нужно подклассифицировать ваш subview - это решение для раскадровки.
Пожалуйста, попробуйте это. Получайте удовольствие!
Ответ 4
- Свифт
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
if <#condition#> { return true }
else { return false }
}
Ответ 5
Используйте это в супер-представлении, не меняя код subviews (так как subviews могут быть введены из других фреймворков или контейнеров):
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *view = [super hitTest:point withEvent:event];
if ([view isDescendantOfView:self])
{
NSLog(@"touched inside");
}
return view;
}
Ответ 6
Если вы хотите обработать событие из суперпредставления (XXXCustomControl в вашем случае) вместо внутреннего представления (ContentView в вашем случае), вы можете написать следующий быстрый код в своем суперпредставлении:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let view = super.hitTest(point, with: event) else { return nil }
if view.isDescendant(of: self) {
// your custom logic
}
return view
}