【发布时间】:2013-09-02 15:37:31
【问题描述】:
我正在尝试创建一个类似于滑块的自定义 UIControl。
此控件将成为一个视图的子视图,该视图还附加了一个点击手势识别器。
现在的问题是这个点击手势识别器取消了发送到我的控件的触摸。有没有办法可以在我的控件代码中覆盖它?
如果我查看 iOS 中的标准控件,它看起来好像 UIButton 有一种覆盖点击手势识别器的方法,但 UISlider 没有。因此,如果我用 UIButton 替换我的自定义控件,点击手势识别器不会触发它的动作,但如果我用滑块替换它会触发它。
编辑:我在 Xcode 中制作了一个小项目来玩。在这里下载 https://dl.dropboxusercontent.com/u/165243/TouchConcept.zip 并尝试更改它,以便
- UICustomControl 不知道点击手势识别器
- 当用户点击黄色框时,UICustomControl 不会被取消
- UICustomControl 没有从 UIButton 继承(这是一个感觉不对的解决方案,以后可能会让我更头疼)
代码:
// 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
【问题讨论】:
-
当我覆盖 UIControl 时,我必须通过覆盖 UIResponder 的 touchesBegan/Moved/Ended/Canceled:withEvent: 来滚动我自己的跟踪,而不是调用 super。我放弃了使用 begin/continue/endTrackingWithTouch:withEvent: 因为它有问题 - 幕后发生的事情太多了。 HTH。
-
示例项目工作正常:touchesBegan,Moved,Ended 不受手势识别器的干扰(因此您可以跟踪滑块的移动),但不移动的触摸会被点击识别器吞噬。 “成为一个视图的子视图,该视图也附加了一个点击手势识别器”意味着无论子视图如何,视图中的每个点击都必须被识别为点击,但这显然不是你想要的。为什么不使用点击手势识别器,而不是使用 touchesBegan/Moved/Ended/Canceled:withEvent: 在您的视图控制器(=响应者链中的超级)来捕获其他未处理的点击?
-
我再次验证,对我来说(iPad 模拟器 6.1)它没有按预期工作:点击手势识别器每次都会触发,每次都会调用 touchesCancelled,但我从未得到 touchesEnded。您提出的解决方案是一种解决方法。目前我正在使用另一种解决方法:从 UIButton 继承。
-
2013-09-04 10:20:27.287 TouchConcept[12033:c07] touchesBegan 2013-09-04 10:20:31.135 TouchConcept[12033:c07] touchesMoved 2013-09-04 10:20 :31.184 TouchConcept[12033:c07] touchesMoved 2013-09-04 10:20:31.999 TouchConcept[12033:c07] touchesMoved 2013-09-04 10:20:32.959 TouchConcept[12033:c07] touchesMoved 2013-09-04 10: 20:36.167 TouchConcept[12033:c07] touchesEnded
-
行为不稳定且不可靠:如果您快速移动并触摸 GR,则会触发,但如果您缓慢移动并缓慢触摸,则不会触发。
标签: ios objective-c