基于位置的 UIGestureRecognizer
Posted
技术标签:
【中文标题】基于位置的 UIGestureRecognizer【英文标题】:Location based UIGestureRecognizers 【发布时间】:2014-01-04 22:22:56 【问题描述】:我正在开发一项功能,它允许 ios 用户滑动屏幕的左半部分并触发一个方法。 UISwipeGestureRecognizers 在 ViewController.m 文件中被调用,这些识别器选择的方法在 MyScene.m 中。
我可以在没有滑动位置设置的情况下让它工作,但我还没有找到一种成功的方法让它只在屏幕的左半部分触发。我在下面包含了一些代码,显示了有无位置要求的示例。
ViewController.m:
- (void)viewDidLayoutSubviews
[super viewDidLayoutSubviews];
SKView * skView = (SKView *)self.view;
if (!skView.scene)
skView.showsFPS = YES;
skView.showsNodeCount = YES;
SKScene *scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:(scene) action:@selector(screenSwipedRight)];
swipeRight.numberOfTouchesRequired = 1;
swipeRight.direction=UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:(swipeRight)];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:(scene) action:@selector(screenSwipedLeft)];
swipeLeft.numberOfTouchesRequired = 1;
swipeLeft.direction=UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:(swipeLeft)];
UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:(scene) action:@selector(screenSwipedUp)];
swipeUp.numberOfTouchesRequired = 1;
swipeUp.direction=UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:(swipeUp)];
MyScene.m:
-(void)screenSwipedRight:(UISwipeGestureRecognizer *)swipedRight
CGPoint touchPoint = [swipedRight locationInView:(self.view)];
NSInteger movePlayer;
if (touchPoint.x <=self.view.bounds.size.width/2)
movePlayer = 1;
else
movePlayer = 2;
if (movePlayer ==1)
CGFloat percentToRight = 1-(self.playerOne.position.x / self.view.bounds.size.width);
NSTimeInterval timeToRight = self.horizontalRunSpeed * percentToRight;
NSLog(@"Percent to right = %f",percentToRight);
NSLog(@"Time to right = %f",timeToRight);
SKAction *moveNodeRight = [SKAction moveToX:self.view.bounds.size.width-self.playerOne.size.width duration:timeToRight];
[self.playerOne runAction:[SKAction sequence:@[moveNodeRight]]];
-(void)screenSwipedLeft
NSLog(@"Screen was swiped to the left");
CGFloat percentToLeft = self.playerOne.position.x / self.view.bounds.size.width;
NSTimeInterval timeToLeft = self.horizontalRunSpeed * percentToLeft;
NSLog(@"Percent to left = %f",percentToLeft);
NSLog(@"Time to left = %f",timeToLeft);
SKAction *moveNodeLeft = [SKAction moveToX:self.playerOne.size.width duration:timeToLeft];
[self.playerOne runAction:[SKAction sequence:@[moveNodeLeft]]];
-(void)screenSwipedUp
NSLog(@"Screen was swiped up");
[self runAction:[SKAction sequence:@[[SKAction runBlock:^ self.physicsWorld.gravity = self.antiGravityAmount;],[SKAction waitForDuration:.25],[SKAction runBlock:^ self.physicsWorld.gravity = self.gravityAmount;]]]];
swipedRight 方法是我试图区分滑动位置的地方。
执行此代码会导致信号 SIGABRT 错误,但仅当我向右滑动时。向左或向上滑动继续正常工作。这可能与从“locationInView”中选择视图有关,但我可能完全错了。
有人知道怎么做吗?
感谢您的帮助。
编辑:这里是关于错误的日志文件-
2014-01-04 18:10:32.316 Romp[584:70b] 找不到 CFBundle 0x976afe0 的可执行文件(未加载)
2014-01-04 18:10:32.375 Romp[584:70b] viewDidLoad 已运行
2014-01-04 18:10:32.425 嬉戏[584:70b] 尺寸:480, 320
2014-01-04 18:10:32.427 Romp[584:70b] 屏幕已初始化
2014-01-04 18:10:33.917 Romp[584:70b] -[MyScene screenSwipedRight]:无法识别的选择器发送到实例 0x9995790
2014-01-04 18:10:33.920 Romp[584:70b] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[MyScene screenSwipedRight]:无法识别的选择器发送到实例 0x9995790'
* 首先抛出调用栈:
( 0 CoreFoundation 0x0185e5e4 异常预处理 + 180 1 libobjc.A.dylib 0x015e18b6 objc_exception_throw + 44 2核心基础0x018fb903-[NSObject(NSObject)不识别选择器:]+275 3 CoreFoundation 0x0184e90b __转发 + 1019 4 核心基础 0x0184e4ee _CF_forwarding_prep_0 + 14 5 UIKit 0x005a8e8c _UIGestureRecognizerSendActions + 230 6 UIKit 0x005a7b00-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383 7 UIKit 0x005a956d-[UIGestureRecognizer _delayedUpdateGesture] + 60 8 UIKit 0x005acacd _UIGestureRecognizerUpdate_block_invoke + 57 9 UIKit 0x005aca4e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317 10 UIKit 0x005a3148 _UIGestureRecognizerUpdate + 199 11 UIKit 0x0026f19a-[UIWindow_sendGesturesForEvent:] + 1291 12 UIKit 0x002700ba-[UIWindow 发送事件:] + 1030 13 UIKit 0x00243e86 -[UIApplication 发送事件:] + 242 14 UIKit 0x0022e18f _UIApplicationHandleEventQueue + 11421 15 核心基础 0x017e783f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 15 16 核心基础 0x017e71cb __CFRunLoopDoSources0 + 235 17 核心基础 0x0180429e __CFRunLoopRun + 910 18 核心基础 0x01803ac3 CFRunLoopRunSpecific + 467 19 核心基础 0x018038db CFRunLoopRunInMode + 123 20 图形服务 0x038039e2 GSEventRunModal + 192 21 图形服务 0x03803809 GSEventRun + 104 22 UIKit 0x00230d3b UIApplicationMain + 1225 23 嬉戏 0x0000615d 主要 + 141 24 libdyld.dylib 0x01e9c70d 开始 + 1 25 ??? 0x00000001 0x0 + 1 )
libc++abi.dylib:以 NSException 类型的未捕获异常终止 (lldb)
【问题讨论】:
错误到底发生在哪一行? 线程 1 队列:com.apple.main-thread.... @autoreleasepool return UIApplicationMain (argc, argv, nil, NSStringFromClass [AppDelegate] 类。将日志文件添加到我的帖子中以获取更多信息信息。 据我了解,问题是您试图通过键入 self.view 在方法中获取 MyScene 的视图。相反,您应该使用 swipeRight.view 更改为 swipedRight.view 导致同样的错误。 【参考方案1】:'-[MyScene screenSwipedRight]: unrecognized selector sent to instance 0x9995790'
相当标准的错误。你这样做:
UISwipeGestureRecognizer *swipeRight =
[[UISwipeGestureRecognizer alloc] initWithTarget:(scene)
action:@selector(screenSwipedRight)];
您将@selector(screenSwipedRight)
注册为回调,这是一个不带参数的方法。您的代码中不存在此方法。
您的方法具有相同的名称,但它需要一个额外的参数UISwipeGestureRecognizer*
,这使得它成为一个不同的方法。所以需要注册为@selector(screenSwipedRight:)
。注意末尾的冒号。
PS:在您的应用中启用exception breakpoint。当发生类似这样的异常时,这将使 Xcode 向您显示代码行。无需进行大量猜测即可进行调试。
【讨论】:
这很好用并且解释得很好。感谢您抽出宝贵时间提供帮助!以上是关于基于位置的 UIGestureRecognizer的主要内容,如果未能解决你的问题,请参考以下文章
UIGestureRecognizer 从头开始制作 UISlider