ios 为什么 UIViewController touchesBegan、touchesMoved 和 touchesEnded 仅在两个触摸中的第一个开始、移动或结束时才被调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12122603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are UIViewController touchesBegan, touchesMoved & touchesEnded only being called when the first of two touches begins, moves or ends?
提问by rankAmateur
I'm having an issue with handling more than one touch through the touchesBegan/Moved/Ended methods of UIViewController. I'm also seeing the same behaviour in a cocos2d app (using ccTouchesBegan/Moved/Ended) so I think this question can be applied to all touch handling in iOS. I've put the code that I'm using below, followed by the results that I'm seeing.
我在通过 UIViewController 的 touchesBegan/Moved/Ended 方法处理多个触摸时遇到问题。我也在 cocos2d 应用程序(使用 ccTouchesBegan/Moved/Ended)中看到了相同的行为,所以我认为这个问题可以应用于 iOS 中的所有触摸处理。我已经把我使用下面的代码,然后是结果我看到。
All methods are implemented on a UIViewController subclass.
所有方法都在 UIViewController 子类上实现。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches Began");
[self logTouchesFor: event];
[super touchesEnded: touches withEvent: event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches Moved");
[self logTouchesFor: event];
[super touchesEnded: touches withEvent: event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches Ended");
[self logTouchesFor: event];
[super touchesEnded: touches withEvent: event];
}
-(void)logTouchesFor:(UIEvent *)event
{
int count = 1;
for (UITouch *touch in event.allTouches)
{
CGPoint location = [touch locationInView: self.view];
NSLog(@"%d: (%.0f, %.0f)", count, location.x, location.y);
count++;
}
}
Now for the interesting results...
现在来看看有趣的结果……
Single Touches Work as Expected
单点触控按预期工作
Let's say I touch the screen with my thumb. I see in the output window that touchesBegan has been called as expected. I move my thumb around and touchesMoved gets called. Then I lift my thumb off the screen and touchesEnded gets called. All this is as expected, I'm including it in the question as a control case - just to be clear that my view controller is receiving touch events and I haven't missed a vc.view.userInteractionEnabled = YES
anywhere.
假设我用拇指触摸屏幕。我在输出窗口中看到 touchesBegan 已按预期调用。我移动我的拇指,touchesMoved 被调用。然后我将拇指从屏幕上抬起,touchesEnded 被调用。所有这一切都符合预期,我将它作为控制案例包含在问题中 - 只是为了清楚我的视图控制器正在接收触摸事件并且我没有错过vc.view.userInteractionEnabled = YES
任何地方。
The Second Touch Doesn't Cause touchesBegan, touchesMoved or touchesEnded to be called
第二次触摸不会导致 touchesBegan、touchesMoved 或 touchesEnded 被调用
This is the most interesting one. Let's say I touch the screen with my thumb (touchesBegan is called) and hold it still on the screen. Then I touch somewhere else on the screen with my index finger, whilst keeping my thumb in the same place. TouchesBegan is not called. Then let's say I move my index finger whilst keeping my thumb absolutely still (this can be tricky but it is possible). TouchesMoved is not called. Then, I lift my index finger off the screen. TouchesEnded is not called. Finally, I move my thumb and touchesMoved is called. Then I lift my thumb from the screen and touchesEnded is called.
这是最有趣的一个。假设我用拇指触摸屏幕(调用 touchesBegan)并将其保持在屏幕上。然后我用食指触摸屏幕上的其他地方,同时将拇指保持在同一位置。未调用 TouchesBegan。然后假设我移动食指,同时保持拇指绝对静止(这可能很棘手,但有可能)。未调用 TouchesMoved。然后,我将食指从屏幕上抬起。未调用 TouchesEnded。最后,我移动我的拇指并调用 touchesMoved。然后我从屏幕上抬起我的拇指并调用 touchesEnded。
Just to be clear: I've set self.view.multipleTouchEnabled = YES
in my viewDidLoad
method.
只是要清楚:我已经设置self.view.multipleTouchEnabled = YES
了我的viewDidLoad
方法。
Information About the Second Touch is Available, Providing the First Touch Moves
提供有关第二次触摸的信息,提供第一次触摸移动
This time I do something very similar to the example immediately above. I touch the screen with my thumb, then index finger whilst keeping my thumb still. TouchesBegan is called when my thumb hits the screen, but not my index finger. Now I move my thumb, and touchesMoved is called. Not only that, but there are two touches in the event.allTouches array (and yes, the second touch is where I would expect it to be). This means that the system is aware that I have touched the screen a second time, but I am not being notified through the touch handling methods on my view controller.
这次我做了一些与上面的例子非常相似的事情。我用拇指触摸屏幕,然后是食指,同时保持拇指不动。当我的拇指击中屏幕而不是食指时,会调用 TouchesBegan。现在我移动我的拇指,并调用 touchesMoved。不仅如此, event.allTouches 数组中有两次触摸(是的,第二次触摸是我期望的位置)。这意味着系统知道我第二次触摸了屏幕,但是我没有通过视图控制器上的触摸处理方法收到通知。
How Can I be Notified About Changes to the Second Touch?
我如何收到有关第二次触摸更改的通知?
I'd really like to be able to respond to changes in the location or state of the second touch as they happen, rather than when the first touch also changes. A lot of the time this won't be an issue because it's very hard to change one touch without impacting on the other, but I have at least one situation where it can be an issue. Am I missing something obvious? Has anyone else noticed this behaviour or had issues with it?
我真的希望能够在第二次触摸的位置或状态发生变化时做出响应,而不是在第一次触摸也发生变化时做出响应。很多时候这不会成为问题,因为改变一个触摸而不影响另一个触摸是非常困难的,但我至少有一种情况可能会成为问题。我错过了一些明显的东西吗?有没有其他人注意到这种行为或有问题?
In case it's relevant, I'm using an iPhone 3GS running iOS 5.1.
如果相关,我使用的是运行 iOS 5.1 的 iPhone 3GS。
回答by rankAmateur
Ok, I started painstakingly rebuilding my project, adding in the files one at a time, and I think I've got it...
好的,我开始煞费苦心地重建我的项目,一次添加一个文件,我想我已经明白了......
There was a subview of the view in question which had userInteractionEnabled == YES
. Once I set this to NO
, my view controller started getting touchesBegan/Moved/Ended calls for each touch. Presumably, the second touch was being claimed by the subview and not making it to my view controller, but I have no idea why this would only happen with the second touch and not the first.
有一个有问题的视图的子视图userInteractionEnabled == YES
。一旦我将其设置为NO
,我的视图控制器开始为每次触摸获取 touchesBegan/Moved/Ended 调用。据推测,第二次触摸被子视图声明并没有进入我的视图控制器,但我不知道为什么这只会发生在第二次触摸而不是第一次触摸中。
I haven't figured out what's going on with the cocos2d project yet, but presumably it's a different issue as there are no subviews or nodes that could be doing the same thing.
我还没有弄清楚 cocos2d 项目发生了什么,但大概这是一个不同的问题,因为没有子视图或节点可以做同样的事情。