У меня есть наложение поверх многих других представлений. Я использую только избыточно для обнаружения некоторого количества касаний на экране, но кроме этого я не хочу, чтобы представление останавливало поведение других представлений внизу, таких как прокрутки и т.д. Как я могу переслать все касания через это наложение вид? Это подкалка UIView.
IOS - нажимать вперед все
Ответ 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
. Теперь он будет работать, вы можете прокручивать стол "через" "держатель".
Но!
В верхней части панели "Держатель" у вас есть несколько ярлыков или значков. Не забывайте, конечно, что они должны быть просто помечены как взаимодействие с пользователем отключено!
В верхней части панели "держатель" у вас есть несколько кнопок. Не забывайте, конечно, они должны быть просто помечены, чтобы взаимодействие с пользователем было включено!
Обратите внимание, что несколько запутанно, сам "держатель" - вид, на котором вы используете
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 (но может быть любое другое представление). Моя конфигурация была следующей:
Это классический случай, когда у меня есть контейнер, который нужно было разместить на заднем плане, с кнопками сбоку. Для макета я включил кнопки в 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. Также вы можете изменить и реализовать другую логику.