点击自定义 UIView 会触发错误的选择器
Tapping on custom UIView fires wrong selector
我在超级视图上有 2 个自定义绘制的子视图和 2 个手势识别器来调用 2 种不同的方法。问题是,当我点击任何视图时,点击第二个子视图仍然会触发第一个方法!这是我的代码:
- (void) addTapGestures{
self.firstTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(firstSelector)];
self.firstTap.numberOfTapsRequired = 1;
[self.firstSubview addGestureRecognizer:self.firstTap];
self.secondTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(secondSelector)];
self.secondTap.numberOfTapsRequired = 1;
[self.secondSubview addGestureRecognizer:self.secondTap];
感谢任何提示!
根据我的评论回答。我能想到的常见问题:
1) self.firstSubview
等于 self.secondSubview
2) 视图重叠 and/or 其中一个视图禁用了用户交互。
第二个竟然是个问题。
您可以通过UIView的hitTest方法获取点击视图。基于此,您可以决定应该调用哪个方法。将此方法放在包含两个子视图的超级视图中。
这是一个例子。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if ([self.firstSubView isEqual:hitView])
{
// You clicked on firstSubView, by returning firstSubView it will call its respective selector method
return self.firstSubView;
}
else if ([self.secondSubView isEqual:hitView])
{
return self.secondSubView;
}
return hitView;
}
Swift 2.0:
尝试:-
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
//make condition here
}
或
使用 UIPanGestureRecognizer。在 ViewController 中,在“父”视图上安装识别器。
var pan = UIPanGestureRecognizer(target:self, action:"pan:")
pan.maximumNumberOfTouches = 1
pan.minimumNumberOfTouches = 1
self.view.addGestureRecognizer(pan)
在识别器动作中,首先抓取事件的位置。然后,根据识别器的状态,实现拖动功能的不同部分。
func pan(rec:UIPanGestureRecognizer) {
var p:CGPoint = rec.locationInView(self.view)
var center:CGPoint = CGPointZero
switch rec.state {
case .Began:
println("began")
self.selectedView = view.hitTest(p, withEvent: nil)
if self.selectedView != nil {
self.view.bringSubviewToFront(self.selectedView!)
}
case .Changed:
if let subview = selectedView {
center = subview.center
var distance = sqrt(pow((center.x - p.x), 2.0) + pow((center.y - p.y), 2.0))
println("distance \(distance)")
if subview is MyView {
if distance > threshold {
if shouldDragX {
subview.center.x = p.x - (p.x % snapX)
}
if shouldDragY {
subview.center.y = p.y - (p.y % snapY)
}
}
}
}
case .Ended:
if let subview = selectedView {
if subview is MyView {
// do whatever
}
}
// must do this of course
selectedView = nil
}
我在超级视图上有 2 个自定义绘制的子视图和 2 个手势识别器来调用 2 种不同的方法。问题是,当我点击任何视图时,点击第二个子视图仍然会触发第一个方法!这是我的代码:
- (void) addTapGestures{
self.firstTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(firstSelector)];
self.firstTap.numberOfTapsRequired = 1;
[self.firstSubview addGestureRecognizer:self.firstTap];
self.secondTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(secondSelector)];
self.secondTap.numberOfTapsRequired = 1;
[self.secondSubview addGestureRecognizer:self.secondTap];
感谢任何提示!
根据我的评论回答。我能想到的常见问题:
1) self.firstSubview
等于 self.secondSubview
2) 视图重叠 and/or 其中一个视图禁用了用户交互。
第二个竟然是个问题。
您可以通过UIView的hitTest方法获取点击视图。基于此,您可以决定应该调用哪个方法。将此方法放在包含两个子视图的超级视图中。 这是一个例子。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if ([self.firstSubView isEqual:hitView])
{
// You clicked on firstSubView, by returning firstSubView it will call its respective selector method
return self.firstSubView;
}
else if ([self.secondSubView isEqual:hitView])
{
return self.secondSubView;
}
return hitView;
}
Swift 2.0:
尝试:-
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
//make condition here
}
或
使用 UIPanGestureRecognizer。在 ViewController 中,在“父”视图上安装识别器。
var pan = UIPanGestureRecognizer(target:self, action:"pan:")
pan.maximumNumberOfTouches = 1
pan.minimumNumberOfTouches = 1
self.view.addGestureRecognizer(pan)
在识别器动作中,首先抓取事件的位置。然后,根据识别器的状态,实现拖动功能的不同部分。
func pan(rec:UIPanGestureRecognizer) {
var p:CGPoint = rec.locationInView(self.view)
var center:CGPoint = CGPointZero
switch rec.state {
case .Began:
println("began")
self.selectedView = view.hitTest(p, withEvent: nil)
if self.selectedView != nil {
self.view.bringSubviewToFront(self.selectedView!)
}
case .Changed:
if let subview = selectedView {
center = subview.center
var distance = sqrt(pow((center.x - p.x), 2.0) + pow((center.y - p.y), 2.0))
println("distance \(distance)")
if subview is MyView {
if distance > threshold {
if shouldDragX {
subview.center.x = p.x - (p.x % snapX)
}
if shouldDragY {
subview.center.y = p.y - (p.y % snapY)
}
}
}
}
case .Ended:
if let subview = selectedView {
if subview is MyView {
// do whatever
}
}
// must do this of course
selectedView = nil
}