IOS - нажимать вперед все

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

Ответ 1

Для передачи штрихов из оверлейного представления в представления под ним реализуйте следующий метод в 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;
}

Swift:

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

Мне нужно было отключить взаимодействие с пользователем!

Objective-C:

myWebView.userInteractionEnabled = NO;

Swift:

myWebView.isUserInteractionEnabled = false

Ответ 3

Это старый поток, но он появился в поиске, поэтому я подумал, что добавлю свой 2c. У меня есть покрытие UIView с subviews и только хочу перехватить штрихи, попавшие в одно из подзонов, поэтому я изменил ответ 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;
}

Ответ 4

Улучшенная версия ответа @fresidue. Вы можете использовать этот подкласс UIView в качестве прозрачного представления касания, передаваемого за пределы его подпредставления. Реализация в 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.isUserInteractionEnabled
      && $0.point(inside: self.convert(point, to: $0), with: event)
    })
  }
}

СОВЕТ:

Скажем, у вас есть большая панель "держатель", возможно, с видом на стол сзади. Вы делаете панель "держатель" PassthroughView. Теперь он будет работать, вы можете прокручивать стол "через" "держатель".

Но!

  1. В верхней части панели "Держатель" у вас есть несколько ярлыков или значков. Не забывайте, конечно, что они должны быть просто помечены как взаимодействие с пользователем отключено!

  2. В верхней части панели "держатель" у вас есть несколько кнопок. Не забывайте, конечно, они должны быть просто помечены, чтобы взаимодействие с пользователем было включено!

  3. Обратите внимание, что несколько запутанно, сам "держатель" - вид, на котором вы используете PassthroughView - должен быть помечен как включенный для взаимодействия с пользователем ON! Это ON!! (В противном случае код в PassthroughView просто никогда не будет вызван.)

Ответ 5

Если представление, которое вы хотите переслать касания, не является subview/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;

Ответ 6

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

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

Я создал подкласс UIStackView со свойством, определяющим подвид, который должен быть сенсорным. Теперь любое прикосновение к боковым кнопкам (включенным в массив * 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
   }
}

Ответ 7

В Swift 5

class ThroughView: UIView {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        guard let slideView = subviews.first else {
            return false
        }

        return slideView.hitTest(convert(point, to: slideView), with: event) != nil
    }
}

Ответ 8

Попробуйте что-нибудь подобное...

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

В приведенном выше коде, например, ваш метод touchsBegan передаст штрихи ко всем подзонам представления.

Ответ 9

Как было предложено @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

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