У меня есть два вида, каждый из которых содержит два подпредставления.
Обнаружение попадания работает нормально, пока два вида сверху не перекрываются.Следовательно, я могу коснуться подпредставления, помеченного буквой A в левой части изображения ниже.
Однако, как только два верхних вида пересекаются, просто не может быть, чтобы представление A получало прикосновения, поскольку представление 1 находится «выше».вид 2 и «съедает» касание.
Оба вида 1 и вид 2 обнаруживают касания, так как их можно перемещать, следовательно, необходимо обнаруживать и реагировать на касания «между» подпредставлениями.
Это означает, что мои два «вид сверху» обнаружения должны сказать: «О, подожди минутку, может быть, я перекрываю какой-то другой вид и должен передать ему событие, и начинать перетаскивание / перемещение только тогда и только тогда, когда нет другихвид "ниже меня" ".
Как бы я это сделал?
Редактировать: Спасибо jaydee3
Сначала это не сработало, что привело к бесконечной рекурсии: каждое представление откладывает своего родного брата, которое, в свою очередь, откладывает обратно на исходное представление:
- (UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView * hit = [super hitTest:point withEvent:event] ;
if (hit == self) {
for (UIView * sibling in self.superview.subviews) {
if (sibling != self) {
CGPoint translated = [self convertPoint:point toView:sibling] ;
UIView * other = [sibling hitTest:translated withEvent:event] ;
if (other) {
return other ;
}
}
}
}
return hit ;
}
Итак, я добавил «помеченный набор», чтобы отслеживать, какой вид уже посещен, и теперь все работает:)
- (UIView *) hitTest: (CGPoint) point withEvent: (UIEvent *) event {
static NSMutableSet * markedViews = [NSMutableSet setWithCapacity:4] ;
UIView * hit = [super hitTest:point withEvent:event] ;
if (hit == nil) return nil ;
if (hit == self) {
for (UIView * sibling in hit.superview.subviews) {
if (sibling != hit) {
if ([markedViews containsObject:sibling]) {
continue ;
}
[markedViews addObject:sibling] ;
CGPoint translated = [hit convertPoint:point toView:sibling] ;
UIView * other = [sibling hitTest:translated withEvent:event] ;
[markedViews removeObject:sibling] ;
if (other) {
return other ;
}
}
}
}
return hit ;
}