Разрешение взаимодействия с UIView под другим UIView

115
задан vikingosegundo 6 September 2012 в 09:58
поделиться

6 ответов

Вы должны создать подкласс UIView для вашего вида сверху и переопределить следующий метод:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // UIView will be "transparent" for touch events if we return NO
    return (point.y < MIDDLE_Y1 || point.y > MIDDLE_Y2);
}

Вы также можете посмотреть на метод hitTest: event:.

97
ответ дан 24 November 2019 в 02:23
поделиться

Вы должны установить upperView.userInteractionEnabled = NO; , иначе верхний вид будет перехватывать касания.

В версии Interface Builder для этого есть флажок в нижней части панели атрибутов просмотра под названием «Взаимодействие с пользователем включено». Снимите флажок, и все будет в порядке.

29
ответ дан 24 November 2019 в 02:23
поделиться

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

Каждый UIView, и это UIWindow, имеет свойство subviews , которое представляет собой NSArray, содержащий все subviews.

Первое subview, которое вы добавляете в view получит индекс 0, следующий индекс 1 и так далее. Вы также можете заменить addSubview: на insertSubview: atIndex: или insertSubview: aboveSubview: и другие методы, которые могут определять положение вашего subview в иерархии.

Поэтому проверьте свой код, чтобы увидеть, какое представление вы добавляете первым в свой UIWindow. Это будет 0, другое - 1.
Теперь, из одного из ваших вложений, чтобы перейти к другому, вы должны сделать следующее:

UIView * theOtherView = [[[self superview] subviews] objectAtIndex: 0];
// or using the properties syntax
UIView * theOtherView = [self.superview.subviews objectAtIndex:0];

Сообщите мне, работает ли это в вашем случае!


(под этим маркером - мой предыдущий ответ):

Если представления должны взаимодействовать друг с другом, они должны делать это через контроллер (то есть, используя популярную модель MVC ).

Когда вы создаете новое представление, вы можете убедиться, что оно регистрируется на контроллере.

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

Если ваше представление этого не делает '

1
ответ дан 24 November 2019 в 02:23
поделиться

Есть кое-что, что вы можете сделать, чтобы перехватить касание в обоих представлениях.

Вид сверху:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   // Do code in the top view
   [bottomView touchesBegan:touches withEvent:event]; // And pass them on to bottomView
   // You have to implement the code for touchesBegan, touchesEnded, touchesCancelled in top/bottom view.
}

Но в этом идея .

2
ответ дан 24 November 2019 в 02:23
поделиться

Есть несколько способов справиться с этим. Мой любимый - переопределить hitTest:withEvent: в представлении, которое является общим супервью (возможно, косвенно) для конфликтующих представлений (похоже, вы называете их A и B). Например, что-то вроде этого (здесь A и B - указатели на UIView, где B - "скрытый", который обычно игнорируется):

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint pointInB = [B convertPoint:point fromView:self];

    if ([B pointInside:pointInB withEvent:event])
        return B;

    return [super hitTest:point withEvent:event];
}

Вы также можете изменить метод pointInside:withEvent:, как предложил gyim. Это позволяет достичь по сути того же результата, эффективно "проделывая дыру" в A, по крайней мере, для касаний.

Другой подход - перенаправление событий, что означает переопределение touchesBegan:withEvent: и подобных методов (таких как touchesMoved:withEvent: и т.д.) для отправки некоторых касаний на другой объект, отличный от того, куда они попали в первый раз. Например, в A вы можете написать что-то вроде этого:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([self shouldForwardTouches:touches]) {
        [B touchesBegan:touches withEvent:event];
    }
    else {
        // Do whatever A does with touches.
    }
}

Однако это не всегда будет работать так, как вы ожидаете! Главное, что встроенные элементы управления, такие как UIButton, всегда будут игнорировать перенаправленные касания. Поэтому первый подход более надежен.

Есть хорошая статья в блоге, объясняющая все это более подробно, а также небольшой рабочий проект xcode для демонстрации идей, доступный здесь:

http://bynomial.com/blog/?p=74

31
ответ дан 24 November 2019 в 02:23
поделиться

Мое решение здесь:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint pointInView = [self.toolkitController.toolbar convertPoint:point fromView:self];

    if ([self.toolkitController.toolbar pointInside:pointInView withEvent:event]) {
       self.userInteractionEnabled = YES;
    } else {
       self.userInteractionEnabled = NO;
    }

    return [super hitTest:point withEvent:event];
}

Надеюсь, это поможет

2
ответ дан 24 November 2019 в 02:23
поделиться