iOS 模拟器在随机时间后停止正确识别手势
iOS simulator stops recognizing gestures correctly after random periods of time
抱歉这么久了。这对我来说是个谜,正在寻找任何人可能拥有的任何指示。
iOS 模拟器中似乎存在一个错误,涉及 UIGestureRecognizers 如何工作和传递触摸点,该错误一直持续到模拟器重新启动。即使杀死应用程序并在模拟器中重新启动它也无法修复它。修复它(暂时)的唯一方法是完全退出模拟器并重新启动它。
我在 UIViewController 子类中有一个 SKView 子类。 SKView 子类占据 UIViewController 的底部,顶部包含一些按钮和其他控件。该游戏涉及点击和平移,由 UIGestureControllers 管理,UIGestureControllers 由拥有 SKScene 子类的 SKView 子类拥有。
经过任意一段时间后,手势停止正常工作。 None 个在 SKScene 拥有的视图中被正确识别。如果我在 SKView 外部和父 UIViewController 中单击,它们就会显示出来,但坐标都是错误的。它还会出现状态错误 - 有时 UIPanGestureRecognizer 认为按下了两根手指而不是一根手指。 UIPanGestureRecognizer 同样关闭。这种行为没有可识别的模式 - 它只是突然开始。
下面是初始化SKView及其场景的相关代码:
SKView * _gameView = [[SKView alloc] initWithFrame : gameRect];
_gameView.clipsToBounds = YES;
// _gameView.scene is an SKScene subclass
CGSize gameSize = CGSizeMake(_gameView.bounds.size.width,
_gameView.bounds.size.width);
_scene = [[GameScene alloc] initWithSize : gameSize];
// Present the scene.
[_gameView presentScene : _scene];
[self.view addSubview : _gameView];
这是注册 UIGestureControllers 的 SKScene 子类中的代码:
- (void) initializeGestureRecognition : (SKView *) view
{
UIPanGestureRecognizer * panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget : self action : @selector (handlePanGesture:)];
UITapGestureRecognizer * tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleTapGesture:)];
panRecognizer.delegate = self;
tapRecognizer.delegate = self;
panRecognizer.maximumNumberOfTouches = 2;
[tapRecognizer requireGestureRecognizerToFail : panRecognizer];
[view addGestureRecognizer : panRecognizer];
[view addGestureRecognizer : tapRecognizer];
}
这是 UIPanGestureRecognizer 的 handlePanGesture 委托的代码:
-(void) handlePanGesture : (UIPanGestureRecognizer*) panRecognizer
{
self.deltaInView = [panRecognizer translationInView : self.view];
self.deltaInScene = CGPointMake(deltaInView.x, -(deltaInView.y));
if (UIGestureRecognizerStateChanged == panRecognizer.state)
{
self.panTouchPoint = [self getPanTouchPoint : panRecognizer];
}
else if (UIGestureRecognizerStateEnded == panRecognizer.state)
{
// Other non-relevant stuff here
}
}
- (CGPoint) didGetPanTouchPoint : (UIPanGestureRecognizer*) panRecognizer
{
CGPoint touchPoint = CGPointMake(0.0, 0.0);
if (2 == panRecognizer.numberOfTouches)
{
CGPoint tempPoint = [self calculateSafeCentroidPointFromRecognizer : panRecognizer];
touchPoint = [self convertPointFromView : tempPoint];
}
else if (1 == panRecognizer.numberOfTouches)
{
CGPoint tempPoint = [panRecognizer locationOfTouch : 0
inView : self.view];
touchPoint = [self convertPointFromView : tempPoint];
}
return touchPoint;
}
- (CGPoint) calculateSafeCentroidPointFromRecognizer : (UIGestureRecognizer*) recognizer
{
CGPoint thisPointInView = [recognizer locationOfTouch : 0
inView : self.view];
CGPoint thatPointInView = [recognizer locationOfTouch : 1
inView : self.view];
CGPoint safePoint = [self calculateCentroidPoint : thisPointInView
secondPoint : thatPointInView];
return safePoint;
}
CGPoint CalculateCentroidPoint(const CGPoint * thisPoint,
const CGPoint * thatPoint)
{
CGPoint centroidPoint = CGPointMake((thisPoint->x + thatPoint->x) / 2.0),
(thisPoint->y + thatPoint->y) / 2.0));
return centroidPoint;
}
这是 UITapGestureRecognizer 的 handleTapGesture 委托的代码:
- (void) handleTapGesture : (UIGestureRecognizer *) gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
{
UITapGestureRecognizer * tapRecognizer = (UITapGestureRecognizer*) gestureRecognizer;
CGPoint viewTouchLocation = [tapRecognizer locationOfTouch : 0
inView : self.view];
CGPoint sceneTouchLocation = [self convertPointFromView : viewTouchLocation];
// Do other stuff here
}
}
需要注意的一件有趣的事情是点击和平移手势识别器都不正确。这不是其中之一。这使我相信存在一些系统性问题。
(或者,更有可能的是,我搞砸了。)
有什么想法吗?
有时模拟器会认为您正在按住 Option (⌥) 键并卡住,这意味着捏合手势助手会在屏幕上激活。要停止此操作,只需再次按 Option。如果这不起作用,请尝试按 Command。
抱歉这么久了。这对我来说是个谜,正在寻找任何人可能拥有的任何指示。
iOS 模拟器中似乎存在一个错误,涉及 UIGestureRecognizers 如何工作和传递触摸点,该错误一直持续到模拟器重新启动。即使杀死应用程序并在模拟器中重新启动它也无法修复它。修复它(暂时)的唯一方法是完全退出模拟器并重新启动它。
我在 UIViewController 子类中有一个 SKView 子类。 SKView 子类占据 UIViewController 的底部,顶部包含一些按钮和其他控件。该游戏涉及点击和平移,由 UIGestureControllers 管理,UIGestureControllers 由拥有 SKScene 子类的 SKView 子类拥有。
经过任意一段时间后,手势停止正常工作。 None 个在 SKScene 拥有的视图中被正确识别。如果我在 SKView 外部和父 UIViewController 中单击,它们就会显示出来,但坐标都是错误的。它还会出现状态错误 - 有时 UIPanGestureRecognizer 认为按下了两根手指而不是一根手指。 UIPanGestureRecognizer 同样关闭。这种行为没有可识别的模式 - 它只是突然开始。
下面是初始化SKView及其场景的相关代码:
SKView * _gameView = [[SKView alloc] initWithFrame : gameRect];
_gameView.clipsToBounds = YES;
// _gameView.scene is an SKScene subclass
CGSize gameSize = CGSizeMake(_gameView.bounds.size.width,
_gameView.bounds.size.width);
_scene = [[GameScene alloc] initWithSize : gameSize];
// Present the scene.
[_gameView presentScene : _scene];
[self.view addSubview : _gameView];
这是注册 UIGestureControllers 的 SKScene 子类中的代码:
- (void) initializeGestureRecognition : (SKView *) view
{
UIPanGestureRecognizer * panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget : self action : @selector (handlePanGesture:)];
UITapGestureRecognizer * tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleTapGesture:)];
panRecognizer.delegate = self;
tapRecognizer.delegate = self;
panRecognizer.maximumNumberOfTouches = 2;
[tapRecognizer requireGestureRecognizerToFail : panRecognizer];
[view addGestureRecognizer : panRecognizer];
[view addGestureRecognizer : tapRecognizer];
}
这是 UIPanGestureRecognizer 的 handlePanGesture 委托的代码:
-(void) handlePanGesture : (UIPanGestureRecognizer*) panRecognizer
{
self.deltaInView = [panRecognizer translationInView : self.view];
self.deltaInScene = CGPointMake(deltaInView.x, -(deltaInView.y));
if (UIGestureRecognizerStateChanged == panRecognizer.state)
{
self.panTouchPoint = [self getPanTouchPoint : panRecognizer];
}
else if (UIGestureRecognizerStateEnded == panRecognizer.state)
{
// Other non-relevant stuff here
}
}
- (CGPoint) didGetPanTouchPoint : (UIPanGestureRecognizer*) panRecognizer
{
CGPoint touchPoint = CGPointMake(0.0, 0.0);
if (2 == panRecognizer.numberOfTouches)
{
CGPoint tempPoint = [self calculateSafeCentroidPointFromRecognizer : panRecognizer];
touchPoint = [self convertPointFromView : tempPoint];
}
else if (1 == panRecognizer.numberOfTouches)
{
CGPoint tempPoint = [panRecognizer locationOfTouch : 0
inView : self.view];
touchPoint = [self convertPointFromView : tempPoint];
}
return touchPoint;
}
- (CGPoint) calculateSafeCentroidPointFromRecognizer : (UIGestureRecognizer*) recognizer
{
CGPoint thisPointInView = [recognizer locationOfTouch : 0
inView : self.view];
CGPoint thatPointInView = [recognizer locationOfTouch : 1
inView : self.view];
CGPoint safePoint = [self calculateCentroidPoint : thisPointInView
secondPoint : thatPointInView];
return safePoint;
}
CGPoint CalculateCentroidPoint(const CGPoint * thisPoint,
const CGPoint * thatPoint)
{
CGPoint centroidPoint = CGPointMake((thisPoint->x + thatPoint->x) / 2.0),
(thisPoint->y + thatPoint->y) / 2.0));
return centroidPoint;
}
这是 UITapGestureRecognizer 的 handleTapGesture 委托的代码:
- (void) handleTapGesture : (UIGestureRecognizer *) gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
{
UITapGestureRecognizer * tapRecognizer = (UITapGestureRecognizer*) gestureRecognizer;
CGPoint viewTouchLocation = [tapRecognizer locationOfTouch : 0
inView : self.view];
CGPoint sceneTouchLocation = [self convertPointFromView : viewTouchLocation];
// Do other stuff here
}
}
需要注意的一件有趣的事情是点击和平移手势识别器都不正确。这不是其中之一。这使我相信存在一些系统性问题。
(或者,更有可能的是,我搞砸了。)
有什么想法吗?
有时模拟器会认为您正在按住 Option (⌥) 键并卡住,这意味着捏合手势助手会在屏幕上激活。要停止此操作,只需再次按 Option。如果这不起作用,请尝试按 Command。