我正在尝试创建一个类似于滑块的自定义UIControl。
此控件是视图的子视图,该视图还附加了一个轻击手势识别器。
现在的问题是这个点击手势识别器会取消发送到我控件的触摸。有没有办法可以在我的控制代码中覆盖它?
如果我查看iOS中的标准控件,看起来UIButton有一种覆盖轻敲手势识别器的方法,但UISlider却没有。因此,如果我用UIButton替换我的自定义控件,则点按手势识别器不会触发其操作,但如果我用滑块替换它,则会这样做。
编辑:我在Xcode中创建了一个小项目。在这里下载https://dl.dropboxusercontent.com/u/165243/TouchConcept.zip并尝试更改它以便
代码:
// inherit from UIButton will give the wanted behavior, inherit from UIView (or UIControl) gives
// touchesCancelled by the gesture recognizer
@interface UICustomControl : UIView
@end
@implementation UICustomControl
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{ NSLog(@"touchesBegan"); }
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ NSLog(@"touchesMoved"); }
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{ NSLog(@"touchesEnded"); }
-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{ NSLog(@"touchesCancelled"); }
@end
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(logTap:)];
[self.view addGestureRecognizer:tapRecognizer];
UIView *interceptingView = [[UICustomControl alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
interceptingView.userInteractionEnabled = YES;
interceptingView.backgroundColor = [UIColor yellowColor];
[self.view addSubview: interceptingView];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void) logTap: (id) sender
{
NSLog(@"gesture recognizer fired");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
答案 0 :(得分:3)
您可以使用“取消触摸视图”属性将手势识别器配置为不取消其附加视图中的触摸:
myGestureRecognizer.cancelsTouchesInView = NO;
答案 1 :(得分:3)
我有点晚了,但对于那些(像我一样)绊倒这个问题的人,我使用了另一种解决方案:
使用手势识别器的代理。
UITapGestureRecognizer *tapGestRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissInfoBox:)];
tapGestRec.delegate = self;
[self.view addGestureRecognizer:tapGestRec];
当手势识别器想要处理/吞下触摸时,在 shouldReceiveTouch 委托功能中进行一种命中测试。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
CGPoint location = [touch locationInView:self.view];
return !CGRectContainsPoint(self.myCustomControl.frame, location) && !CGRectContainsPoint(self.myOtherCustomControl.frame, location);
}
我在我的ViewController中完成了所有这些操作,这样UIControl就不必知道任何兄弟视图,并且手势识别器不会“偷”'从我的自定义控件中点击,只处理' uncaught'水龙头。
此外,通过这种方式,您不会触发手势识别器和自定义控件,这将通过 cancelsTouchesInView 进行。
顺便说一句,也许它适用于UIButton,因为UIButton在内部使用手势识别器?我认为他们互相理解,而UIControls和识别者却没有。但不确定。答案 2 :(得分:0)
您应该遵循本教程
它向您展示了如何制作自定义uiview。
答案 3 :(得分:0)
在您的gestureRecognizerShouldBegin(_:)
子类中覆盖UIControl
。
public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer.isKind(of: UITapGestureRecognizer.self) {
return false
} else {
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
}