iOS - вперед все касаются через вид


75

У меня есть вид сверху поверх многих других видов. Я использую overaly для обнаружения некоторого количества касаний на экране, но кроме этого я не хочу, чтобы представление останавливало поведение других представлений под ним, которые являются просмотрами прокрутки и т. Д. Как я могу переправить все касания через это оверлейное представление? Это подкаталоги UIView.

0

попробовать что-то вроде этого ...

for (UIView *view in subviews) 
    [view touchesBegan:touches withEvent:event]; 

Кода выше, в методе touchesBegan, например, будет проходить прикосновения ко всему подобозрение зрения.

+6

Проблема с этим подходом AFAIK является то, что пытается передать штрихи к классам рамках UIKit чаще всего не имеют эффект. Согласно документации Apple, классы классов UIKit не предназначены для получения штрихов, у которых свойство вида установлено на другое представление. Таким образом, этот подход работает в основном для пользовательских подклассов UIView. 02 мар. 112011-03-02 23:05:35


4

Если вид вы хотите, чтобы направить штрихи не случается подвид/SuperView, вы можете создать пользовательское свойство в вашем UIView подкласс так:

@interface SomeViewSubclass : UIView { 

    id forwardableTouchee; 

} 
@property (retain) id forwardableTouchee; 

Убедитесь синтезировать это в вашем .m:

@synthesize forwardableTouchee; 

А затем включают следующее в любом из методов UIResponder, таких как:

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

    [self.forwardableTouchee touchesBegan:touches withEvent:event]; 

} 

Где бы вы ни создать экземпляр UIView, установите свойство forwardableTouchee на любой вид вы хотите события, которые будут направлены на:

SomeViewSubclass *view = [[[SomeViewSubclass alloc] initWithFrame:someRect] autorelease]; 
    view.forwardableTouchee = someOtherView; 

75

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

Objective-C:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { 
    NSLog(@"Passing all touches to the next view (if any), in the view stack."); 
    return NO; 
} 

Свифта:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    print("Passing all touches to the next view (if any), in the view stack.") 
    return false 
} 
+2

У меня такая же проблема, но я хочу, если я масштабирую/поворачиваю/перемещая взгляд с жестом, тогда он должен возвращать да и для события отдыха он должен возвращать нет, как я могу это достичь? 12 авг. 132013-08-12 06:27:33


58
myWebView.userInteractionEnabled = NO; 

было все, что мне нужно!


38

Это старая тема, но она пришла к поиску, поэтому я подумал, что добавлю свой 2c. У меня есть покрытие UIView с подвидами, и только хочу перехватить штрихи, которые поражают один из подвидов, поэтому я изменил ответ PixelCloudSt на

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    for (UIView* subview in self.subviews) { 
     if ([subview hitTest:[self convertPoint:point toView:subview] withEvent:event] != nil) { 
      return YES; 
     } 
    } 
    return NO; 
} 
+1

Вам необходимо создать пользовательский подкласс UIView (или подкласс любого другого подкласса UIView, такого как UIImageView или что-то еще) и переопределить эту функцию. По сути, подкласс может иметь полностью пустой «@interface» в файле .h, а функция выше - все содержимое «@implementation». 07 мар. 142014-03-07 16:01:14


-1

Как было предложен @PixelCloudStv, если вы хотите, чтобы бросить прикоснулись от одного вида к другой, но с какой-то дополнительный контроль за этим процессом - подкласс UIView

// заголовок

@interface TouchView : UIView 

@property (assign, nonatomic) CGRect activeRect; 

@end 

// реализация

#import "TouchView.h" 

@implementation TouchView 

#pragma mark - Ovverride 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    BOOL moveTouch = YES; 
    if (CGRectContainsPoint(self.activeRect, point)) { 
     moveTouch = NO; 
    } 
    return moveTouch; 
} 

@end 

После того, как в интерфейсеBuilder просто установите класс View to TouchView и установите активный прямоугольник с вашим прямоугольником. Также вы можете изменить и реализовать другую логику.


3

У меня была аналогичная проблема с UIStackView (но может быть любым другим видом). Моя конфигурация была следующая: View controller with containerView and StackView

Это классический случай, когда у меня есть контейнер, который должен был быть помещен в фоновом режиме, с помощью кнопок на стороне. Для целей компоновки я включил кнопки в UIStackView, но теперь средняя (пустая) часть stackView перехватывает касания :-(

Что я сделал, это создать подкласс UIStackView с свойством, определяющим subView, которое должно быть touchable. Теперь любое касание боковых кнопок (входящих в массив * viewsWithActiveTouch *) будет передаваться кнопкам, в то время как любое касание к стеклу в любом месте, кроме этих представлений, не будет перехвачено и, следовательно, передано на все, что угодно ниже точки зрения стека.

/** Subclass of UIStackView that does not accept touches, except for specific subviews given in the viewsWithActiveTouch array */ 
class NoTouchStackView: UIStackView { 

    var viewsWithActiveTouch: [UIView]? 

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { 

    if let activeViews = viewsWithActiveTouch { 
     for view in activeViews { 
      if CGRectContainsPoint(view.frame, point) { 
       return view 

      } 
     } 
    } 
    return nil 
    } 
} 

14

Улучшенная версия @fresidue ответ. Вы можете использовать этот UIView подкласс, как прозрачный вид прохождения прикосновений оу tside его subview. Реализация в Objective-C:

@interface PassthroughView : UIView 

@end 

@implementation PassthroughView 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    for (UIView *view in self.subviews) { 
     if (!view.hidden && [view pointInside:[self convertPoint:point toView:view] withEvent:event]) { 
      return YES; 
     } 
    } 
    return NO; 
} 

@end 

и в Swift:

class PassthroughView: UIView { 
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    return subviews.contains(where: { 
     !$0.isHidden && $0.point(inside: self.convert(point, to: $0), with: event) 
    }) 
    } 
}