我正在尝试创建一个类似于滑块的自定义 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
Run Code Online (Sandbox Code Playgroud)
您可以使用“取消视图中的触摸”属性将手势识别器配置为不取消其附加视图中的触摸:
myGestureRecognizer.cancelsTouchesInView = NO;
Run Code Online (Sandbox Code Playgroud)
我有点晚了,但是对于那些(像我一样)绊倒这个问题的人,我使用了另一种解决方案:
使用手势识别器的委托。
UITapGestureRecognizer *tapGestRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissInfoBox:)];
tapGestRec.delegate = self;
[self.view addGestureRecognizer:tapGestRec];
Run Code Online (Sandbox Code Playgroud)
然后当手势识别器想要处理/吞下触摸时,在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);
}
Run Code Online (Sandbox Code Playgroud)
我在我的 ViewController 中完成了所有这些,这样 UIControl 就不必知道任何兄弟视图,并且手势识别器不会从我的自定义控件中“窃取”点击,而只处理“未捕获”的点击。
此外,这样您就不会同时触发手势识别器和自定义控件,这在cancelsTouchesInView中会发生。
顺便说一句,也许它适用于 UIButton 因为 UIButton 在内部使用手势识别器?我认为它们相互理解,而 UIControls 和识别器则不理解。虽然不确定。
小智 5
gestureRecognizerShouldBegin(_:)在你的子类中重写UIControl。
public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer.isKind(of: UITapGestureRecognizer.self) {
return false
} else {
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4937 次 |
| 最近记录: |