2012-03-26 3 views
2

У меня есть два вида, каждый из которых содержит два подзаголовка.UITouch на перекрывающихся UIViews

Обнаружение попадания отлично работает, пока два верхних вида не перекрываются. Следовательно, я могу коснуться субвью с надписью A в левой части изображения ниже.

Однако, как только верхние два вида перекрываются, нет никакого способа, чтобы A-представление получало касания, поскольку вид 1 является «над» видом 2 и «ест» прикосновение.

Как View 1, так и View 2 обнаруживают касания, поскольку их можно перемещать, следовательно, необходимо обнаруживать и реагировать на касания «между» подзонами.

Это означает, что мои два обнаружения «сверху» должны сказать: «Ой, подождите минуту, может быть, я осваиваю какое-то другое представление и должен передать ему событие, и только начинаю перетаскивать/перемещаться, если и только если никакая другая точка зрения «ниже меня».

Как бы я это сделал? enter image description here

Edit: Благодаря 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 ; 
} 

ответ

3

Создайте собственный подкласс для вашего представления (содержащий два других объекта) и перезапишите для него метод hitTest:. В этом методе проверьте, является ли представление hitTest одним из двух подзонов, иначе возвращайте nil. Таким образом, все ваши прикосновения будут игнорироваться по вашему окружающему виду. В результате получилось прикосновение к виду ниже, которое может справиться с этим.

// редактировать: (Вы получаете вид Трассировка с помощью вызова UIView* view = [super hitTest:withEvent:];.)

// edit2: я больше думал о чем-л так: :)

- (UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
    UIView * hit = [super hitTest:point withEvent:event] ; 

    if (hit == self) { 
     return nil; 
    } 

    return hit ; 
} 

;)

+0

отредактирован мой ответ. Возможно, это работает лучше. – calimarkus

+0

Это не сработало бы, потому что это предотвратило бы то, что верхние представления вообще не обрабатывают какое-либо событие. В моем отредактированном вопросе я предоставил код, который теперь работает. Еще раз спасибо. – verec

+0

aah я не знал, что вам нужны прикосновения к этим взглядам. отлично. пожалуйста. – calimarkus

Смежные вопросы