自定义的UIView无法接收触摸事件

3

我正在为我的应用程序构建一个自定义滑动条。

我在Github上找到了一份库,作为灵感来源。

我创建了一个文件:NKSlider,它是UIView的子类,并像库一样实现了drawRect,并实现了touchesMoved:withEvent:touchesBegan:withEvent:方法。但是没有任何触摸事件被调用。

这是我如何将这个自定义视图添加到我的视图控制器中:

NKHandler *nk = [[NKHandler alloc] init];
nk.frame = CGRectMake(20, 20, 280, 36);
[self.view addSubview:nk];
[self.view addSubview:[[NKHandler alloc] initWithFrame:CGRectMake(20, 60, 280, 100)]];

这是类的定义。我做错了什么吗?
这里是.h文件。
#import <UIKit/UIKit.h>

@interface NKHandler : UIView

@end

并且 .m

#import "NKHandler.h"

static inline CGPoint CGPointTopCenter(CGRect rect) {
  CGPoint p; p.x = rect.origin.x + (rect.size.width / 2); p.y = rect.origin.y; return p;
}
static inline CGPoint CGPointBottomCenter(CGRect rect) {
  CGPoint p; p.x = rect.origin.x + (rect.size.width / 2); p.y = rect.origin.y + rect.size.height; return p;
}
static inline CGPoint CGPointLeftCenter(CGRect rect) {
  CGPoint p; p.x = rect.origin.x; p.y = rect.origin.y + (rect.size.height / 2); return p;
}
static inline CGPoint CGPointRightCenter(CGRect rect) {
  CGPoint p; p.x = rect.origin.x + rect.size.width; p.y = rect.origin.y + (rect.size.height / 2); return p;
}

@implementation NKHandler {
  int _selectedStep;
}

-(id)init {
  self = [super init];
  if (self) {
    self.backgroundColor = [UIColor clearColor];

    self.clipsToBounds = NO;
    self.opaque = YES;

    _selectedStep = 5;   
  }
  return self;
}

-(void) setStep:(int) step {
  _selectedStep = step;
  [self setNeedsDisplay];
}

-(void)layoutSubviews {
  ... layout stuff ...
}
-(void)drawRect:(CGRect)rect {
  ... Boring drawing stuff ..
}

#pragma mark - Touch Handling

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  NSLog(@"%s", __PRETTY_FUNCTION__);
  [self setStep:(_selectedStep+1)%11];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  NSLog(@"%s", __PRETTY_FUNCTION__);
}

@end

UIView的指定初始化方法是initWithFrame:(如果你使用Interface Builder,还可以使用initWithCoder),所以当你调用[self.view addSubview:[[NKHandler alloc] initWithFrame:...时,你的初始化代码永远不会被执行。 - Guillaume
在我贴出的代码中,我已经添加了两个视图到我的“viewcontroller”,一个是使用我的自定义“init”方法创建的,另一个是使用“initWithFrame:”创建的,在这两个视图中,触摸都不起作用。 - Nicos Karalis
4个回答

4
nk.userInteractionEnabled = YES;

你尝试过在你的自定义类中添加touches began方法,然后调用super将它们传回到原始视图吗? - Bill Burgess
原始视图是什么?在我的ViewController中,我添加了一个子视图,这个子视图是我的自定义视图。没有 touches 的 super。 - Nicos Karalis
即便如此,您有一个自定义类(UIView),它作为子视图添加到您的视图中。触摸事件将传递到您的子视图并且不会被处理。在那里处理触摸事件,然后只需调用super将其传回到您的主视图,而不是子视图。 - Bill Burgess
1
显然这是一个bug,在清理和重建后已经修复了,对于回复晚了我很抱歉。 - Nicos Karalis

2
如果 userInteractionEnabled trick 不起作用,也许你应该检查视图的 父视图自动调整大小属性。我像下面那样进行了更改,因为故事板最初在纵向模式下加载,但我在横向模式下呈现它,所以父视图的高度变为0像素。即使视图本身保持其高度,父级仍然变为0像素,所以视图没有获得事件。

enter image description here enter image description here


0

我看到这行代码会影响UIView事件:

contentView.translatesAutoresizingMaskIntoConstraints = NO;

在使用pushViewController和popViewControllerAnimated方法推送和弹出视图控制器后,这一行可能会引起头痛。一旦您的contentView再次显示,您可能会发现事件处理不起作用。


0
这可能是一个非常特殊的情况,但我在编程时遇到了这个问题。我不小心让我的自定义视图类从UICollectionViewCell继承,但在XIB中使用的元素却是UIView

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接