UIControl不接触

我有一个UIControl实现触摸开始的方法是这样的:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; //More code goes here 

这个UIControl的子类在视图控制器中实例化,然后作为子视图添加到该视图控制器。 我在UIControl的接触开始方法有一个断点,并且方法永远不会被调用。 我一直在做一些阅读,似乎视图控制器有一些决定是否将触摸事件传递给子视图的逻辑。 奇怪的是我在同一个视图控制器中有一个不同的UIControl的子类,触摸事件会在用户触摸时传递给它! 以下是完整的代码:

。H

 #import <UIKit/UIKit.h> @interface CustomSegment : UIView @property (nonatomic, strong) UIImageView *bgImageView; @property (nonatomic, assign) NSInteger segments; @property (nonatomic, strong) NSArray *touchDownImages; @property (nonatomic, readonly, assign) NSInteger selectedIndex; @property (nonatomic, weak) id delegate; - (id)initWithPoint:(CGPoint)point numberOfSegments:(NSInteger)_segments andTouchDownImages:(NSArray *)_touchDownImages; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; @end 

.M

 #import "CustomSegment.h" @implementation CustomSegment @synthesize bgImageView, segments, touchDownImages, selectedIndex, delegate; - (id)initWithPoint:(CGPoint)point numberOfSegments:(NSInteger)_segments andTouchDownImages:(NSArray *)_touchDownImages { self = [super initWithFrame:CGRectMake(point.x, point.y, [[_touchDownImages objectAtIndex:0] size].width, [[touchDownImages objectAtIndex:0] size].height)]; if (self) { touchDownImages = _touchDownImages; segments = _segments; bgImageView = [[UIImageView alloc] initWithImage:[touchDownImages objectAtIndex:0]]; [self addSubview:bgImageView]; } return self; } - (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { return YES; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //[super touchesBegan:touches withEvent:event]; UITouch *touch = [touches anyObject]; float widthOfSegment = [self frame].size.width / segments; float bottomPoint = 0; float topPoint = widthOfSegment; for (int i = 0; i < segments; i++) { if ([touch locationInView:self].x > bottomPoint && [touch locationInView:self].x < topPoint) { [bgImageView setImage:[touchDownImages objectAtIndex:i]]; selectedIndex = i; return; } else { bottomPoint = topPoint; topPoint += topPoint; } } } @end 

tl; dr将UIControl的所有子视图设置为setUserInteractionEnabled:NO 。 UIImageView的默认设置为true。

原始post

我最近发现的一件事是,如果UIControl的最顶层子视图有setUserInteractionEnabled:NO ,它会有setUserInteractionEnabled:NO 。 我到达这个,因为我有一个UIImageView的UIControl子类,因为它只有子视图,它工作正常。 UIImageView默认情况下将userInteractionEnabled设置为NO

我还有另一个UIControl与UIView,因为它是最顶级的子视图(技术上相同的UIControl在不同的状态)。 我相信UIView默认为userInteractionEnabled == YES ,这阻止了UIControl处理的事件。 设置UIView的userInteractionEnabled NO解决了我的问题。

我不知道这里是否是同样的问题,但也许会有帮助?

– 编辑:当我说最上面的视图…可能设置UIControl的所有子视图setUserInteractionEnabled:NO

检查所有父视图的frame 。 规则是,如果视图的子视图(或其部分)在视图边界之外,则不会接收触摸事件。

有可能是另一个视图覆盖你的UIControl,并阻止它接收触摸事件。 另一种可能性是userInteractionEnabled在某处被错误地设置为NO

编辑:我看到你在上面添加更多的代码。 你有没有确认你的视图的框架的宽度和高度大于零? 它看起来像你直接调用NSArray(这是“ID”)的对象上的“大小”。 我不知道你是怎么做到的,没有演员(也许括号没有通过上面?),但如果你以某种方式把它拉下来,我不会感到惊讶,如果它是一个无效的价值。

可能性:

  • 您可能忘了设置UIControl的代理。
  • 接触到触摸的其他UIControl遮挡/覆盖UIControl。

很公平。 最近重新调查了这个(UIControl是非常糟糕的logging),并意识到跟踪触摸是touchesBegan / Ended,而不是一个额外的替代,所以很抱歉。 我会扭转投票,但它不会让我:(

首先,你为什么叫[super touchesBegan:touches withEvent:event]; ? 该呼叫将该事件转发给下一个响应者。 通常只有当你不想处理事件的时候才会这样做。 你确定你知道你在那里做什么?

一个想法,为什么它不起作用 – 可能是你有一个手势识别器,首先处理事件?

无论如何,你真的需要重写touchesBegan吗? UIControl是为了跟踪触摸事件本身,并呼吁你的处理程序作出回应。 UIControl文档说明如何inheritance它。

子类化笔记

您可能要扩展一个UIControl子类的原因有两个:

  • 观察或修改对特定事件的目标的动作消息的发送

    为此,请覆盖sendAction:to:forEvent:,评估传入的select器,目标对象或UIControlEvents位掩码,然后根据需要继续。

  • 要提供自定义的跟踪行为(例如,更改高亮显示的外观)

    为此,请重写以下一个或所有方法:beginTrackingWithTouch:withEvent:,continueTrackingWithTouch:withEvent:,endTrackingWithTouch:withEvent :.

UIView实例无法响应事件,所以没有办法,直到您当前的configuration,触发您的操作方法?

尝试将视图的类更改为UIControl类的实例!