UIControl未接收到触摸

时间:2012-02-19 14:28:45

标签: iphone ios uitouch uicontrol

我有一个UIControl,它实现了触摸开始方法,如下所示:

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

UIControl的这个子类在视图控制器中实例化,然后作为子视图添加到该视图控制器。我在UIControl的touches begin方法中有一个断点,并且该方法永远不会被调用。我一直在做一些阅读,看起来View Controller有一些逻辑决定是否将触摸事件传递给它的子视图。奇怪的是,我在同一个视图控制器中有一个不同的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

8 个答案:

答案 0 :(得分:66)

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

原帖

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

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

我不知道这是否是同一个问题,但也许这会有所帮助?

- 编辑:当我说最顶层视图时...可能将UIControl的所有子视图设置为setUserInteractionEnabled:NO

答案 1 :(得分:2)

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

答案 2 :(得分:1)

另一个视图可能会覆盖您的UIControl,并阻止其接收触摸事件。另一种可能性是userInteractionEnabled错误地设置为NO

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

答案 3 :(得分:0)

的可能性:

  • 您可能忘记为UIControl设置委托。
  • 接收触摸的另一个UIControl遮挡/覆盖UIControl。

答案 4 :(得分:0)

首先,你为什么打电话给[super touchesBegan:touches withEvent:event];?此调用将事件转发给下一个响应者。通常只有在您不想处理事件时才会这样做。你确定你知道你在那里做什么吗?

为什么它不起作用的想法 - 是否有一个手势识别器首先处理事件?

无论如何,你真的需要覆盖touchesBegan吗? UIControl用于跟踪触摸事件本身并致电您的处理程序作为响应。并且UIControl文档说如何将其子类化。

  

子类注释

     

您可能希望扩展UIControl子类有以下两个原因:

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

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

  •   
  • 提供自定义跟踪行为(例如,更改突出显示外观)

      为此,请覆盖以下一个或所有方法:beginTrackingWithTouch:withEvent:,continueTrackingWithTouch:withEvent:,endTrackingWithTouch:withEvent:。

  •   

答案 5 :(得分:0)

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

答案 6 :(得分:0)

您可能需要在intrinsicContentSize子类中覆盖UIControl

override var intrinsicContentSize: CGSize {
    return CGSize(width: 150, height: 100)
}

我不太了解它是如何修复的或为什么,但是它可以工作。它甚至不需要是您控件的确切大小。

答案 7 :(得分:-2)

UIView实例无法响应事件,因此在当前配置下无法触发您的操作方法?

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