UIScrollView触摸vs子视图 [英] UIScrollView touches vs subview touches

查看:74
本文介绍了UIScrollView触摸vs子视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以帮忙整理一个noob吗?我已经发布了这个问题在各种论坛,并没有收到任何答案,而许多搜索其他答案已经得到了stackOverflow,所以我希望这是地方。

Please can someone help sort a noob out? I've posted this problem on various forums and received no answers, while many searches for other answers have turned up stackOverflow, so I'm hoping this is the place.

我有一个BeachView.h(UIScrollView的子类,沙滩的图片)覆盖了随机数的Stone.h(UIImageView的子类,随机PNG的石头,userInteractionEnabled =是接受触摸)。

I've got a BeachView.h (subclass of UIScrollView, picture of a sandy beach) covered with a random number of Stone.h (subclass of UIImageView, a random PNG of a stone, userInteractionEnabled = YES to accept touches).

如果用户触摸和在海滩上移动,它应该滚动。
如果用户敲击石头,它应该调用方法touchedStone。
如果用户敲击没有石头的海滩,它应该调用方法touchedBeach。

If the user touches and moves on the beach, it should scroll. If the user taps a stone, it should call method "touchedStone". If the user taps the beach where there is no stone, it should call method "touchedBeach".

现在,我意识到这听起来很简单。每个人和一切都告诉我,如果有一些UIScrollView接受触摸,它应该传递控制到它。所以当我触摸和拖动,它应该滚动;但是如果我点击,它在石头上,它应该忽略沙滩水龙头和接受石头水龙头,是吗?

Now, I realize this sounds dead simple. Everyone and everything tells me that if there's something on a UIScrollView that accepts touches that it should pass control on to it. So when I touch and drag, it should scroll; but if I tap, and it's on a stone, it should ignore beach taps and accept stone taps, yes?

但是,似乎两个意见都接受水龙头和调用touching和triggeredBeach。此外,海滩水龙头首先发生,所以我甚至不能放在如果碰到石头,然后不运行touchingBeach类型标志。

However, it seems that both views are accepting the tap and calling both touchedStone AND touchedBeach. Furthermore, the beach tap occurs first, so I can't even put in a "if touchedStone then don't run touchedBeach" type flag.

这里是一些代码。
On BeachView.m

Here's some code. On BeachView.m


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     if (self.decelerating) { didScroll = YES; }
        else { didScroll = NO; }

     UITouch *touch = [[event allTouches] anyObject];
     CGPoint touchLocation = [touch locationInView:touch.view];
     NSLog(@"touched beach = %@", [touch view]);
     lastTouch = touchLocation;
     [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
     didScroll = YES;
     [super touchesMoved:touches withEvent:event];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
     if (didScroll == NO && isPaused == NO) { 
          [self touchedBeach:YES location:lastTouch];
     }
     [super touchesEnded:touches withEvent:event];
}

On Stone.m

On Stone.m


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     [parent stoneWasTouched]; // parent = ivar pointing from stone to beachview
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch *touch = [[event allTouches] anyObject];
     CGPoint touchLocation = [touch locationInView:touch.view];
     NSLog(@"touched stone = %@", [touch view]);
     [parent touchedStone:YES location:touchLocation];
}

点击之后,我的NSLog看起来像这样:

After a stone tap, My NSLog looks like this:


Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched Stone = <Stone: 0x1480c0>
ran touchedStone

甚至陌生人是如果我采取touchesBegan和touchesEnded从Stone.m但留下userInteractionEnabled = YES,beachView注册两个触摸本身,但返回石头作为它触摸的视图(第二次)。

So it's actually running both. What's even stranger is if I take the touchesBegan and touchesEnded out of Stone.m but leave userInteractionEnabled = YES, the beachView registers both touches itself, but returns the Stone as the view it touched (the second time).


Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched beach = <Stone: 0x1480c0>
ran touchedBeach

因此,我一直在尝试排序这几天。我如何使它如此一个轻敲的石头只触摸摸过的石头和一个轻敲的海滩只有toucBeach电话?

So PLEASE, I've been trying to sort this for days. How do I make it so a tapped stone calls only touchedStone and a tapped beach calls only touchedBeach? Where am I going wrong?

推荐答案

在iPhone OS 3.0之前,UIScrollView的hitTest:withEvent:方法总是返回self,

Prior to iPhone OS 3.0, the UIScrollView's hitTest:withEvent: method always returns self so that it receives the UIEvent directly, only forwarding it to the appropriate subview if and when it determines it's not related to scrolling or zooming.

我不能真正地评论iPhone OS 3.0,而是直接接收UIEvent,只有当它确定它与滚动或缩放无关时,才将其转发到相应的子视图。因为它在NDA下,但检查你的iPhone SDK版本说明为iPhone OS 3.0 beta 5):

I couldn't really comment on iPhone OS 3.0 as it's under NDA, but check your "iPhone SDK Release notes for iPhone OS 3.0 beta 5" :)

如果你需要目标3.0之前,你可以重写hitTest :withEvent:在BeachView中,如果CGPoint实际上在一个石头上,设置一个标志来忽略下一个海滩触摸。

If you need to target pre-3.0, you could override hitTest:withEvent: in BeachView and set a flag to ignore the next beach touch if the CGPoint is actually in a stone.

但是你试过简单地将你的呼叫移动到[super touches *:withEvent:]从覆盖的方法结束到开始?这可能会导致石头水龙头首先发生。

But have you tried simply moving your calls to [super touches*:withEvent:] from the end of your overridden methods to the start? This might cause the stone tap to occur first.

这篇关于UIScrollView触摸vs子视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆