Братский подвид не получает прикосновений в iPhone - PullRequest
0 голосов
/ 19 декабря 2011

У меня есть представление (parent) с двумя подпредставлениями, одно сверху (topChild) другого (bottomChild).

Если я нажму на экран только topChild и parent, получим событие касания.

Что я должен изменить, чтобы распространить событие касания на bottomChild?

код:

- (void)viewDidLoad
{
    [super viewDidLoad];
    MYView* parent = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    parent.tag = 3;
    parent.backgroundColor = [UIColor redColor];

    MYView* bottomChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
    bottomChild.tag = 2;
    bottomChild.backgroundColor = [UIColor blueColor];
    [parent addSubview:bottomChild];

    MYView* topChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
    topChild.tag = 1;
    topChild.backgroundColor = [UIColor greenColor];
    [parent addSubview:topChild];
    [self.view addSubview:parent];
}

Где MYView - это подкласс UIView, который регистрирует только touchesBegan.

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%d", self.tag);
    [super touchesBegan:touches withEvent:event];
}

Результат:

enter image description here

Прикосновение к зеленой области приводит к следующему журналу:

TouchTest[25062:f803] 1
TouchTest[25062:f803] 3

Моей первой идеей было заставить parent передавать все touchesSomething звонки своим дочерним элементам, но (A) Я подозреваю, что может быть более простое решение и (B) Я не знаю, какой ребенок отправил событие родителю, и отправка touchesSomething сообщений дважды одному и тому же представлению может вызвать махинации.

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

Ответы [ 2 ]

1 голос
/ 19 декабря 2011

У вас есть интересная проблема, которая, вероятно, лучше всего решается путем переосмысления структуры ваших вещей.Но чтобы заставить его работать так, как вы предлагаете, вам нужно перехватить событие касания в текущем виде сверху, передать его родителю, а затем распространить его вниз по всем подпредставлениям родительского представления.Чтобы это работало, вам понадобится touchesBegan: (или любой другой метод, используемый для перехвата касания), чтобы ничего не делать во всех представлениях, выполняя действие только в методе, вызываемом родительским представлением.

Это действительно другой способ сказать: не обрабатывайте касания в представлениях, перехватывайте их, но уведомляйте представление родительского представления и затем вызывайте методы подпредставления, как требуется, чтобы добиться желаемого эффекта.

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    // Do nothing, parent view calls my parentNotifiedTouchesBegan method
    [self.superview touchesBegan:touches withEvent:event];
}

- (void) parentNotifiedTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    // Act on the touch here just as my sibling views are doing
}

Примечание. Я изменилsuper до self.superview в этом коде.Вы можете или не можете также хотеть вызывать метод super в зависимости от того, что вы делаете, и от места для вызова, которое может быть в parentNotifiedTouchesBegan.

Вы можете знать, какой subView отправил событиеКонечно, просто используйте пользовательский метод для уведомления суперпредставления вместо вызова его touchesBegan:.Используйте аргумент self.

0 голосов
/ 20 декабря 2011

Если вам не нужны прикосновения к детям, установите

bottomChild.userInteractionEnabled = NO;
topChild.userInteractionEnabled = NO;
...