【问题标题】:Why does creating a UIGestureRecognizer subclass in an nib cause a crash using a UISplitViewController为什么在笔尖中创建 UIGestureRecognizer 子类会导致使用 UISplitViewController 崩溃
【发布时间】:2011-12-20 15:22:48
【问题描述】:

我对在我拥有的 ViewController 子类中使用 UIGestureRecognizer 子类 (UILongPressGestureRecognizer) 很感兴趣。我的 ViewController 有一个 UIToolBar 并且以编程方式我可以创建一个附加到 UIToolBar 的 UILongPressGestureRecognizer 实例并让一切正常。我的 ViewController 采用 UIGestureRecognizerDelegate 协议。在 ViewController 我有:

//My ViewController.h
@interface MyViewController: UIViewController<UIGestureRecognizerDelegate>
/* ... */

@property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
@property (nonatomic, retain) IBOutlet UILongPressGestureRecognizer *longPressGesureRecognizer;

/* ... */

- (IBAction)handleGesture;

@end

下面的代码就可以工作了:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //configure UILongPressGestureRecognizer
    if(self.longPressGesureRecognizer == nil){
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture)];

        longPress.minimumPressDuration = 1.5;
        longPress.numberOfTouchesRequired = 1;
        longPress.delegate = self;

        self.longPressGesureRecognizer = longPress;
        [self.toolbar addGestureRecognizer:self.longPressGesureRecognizer];

        [longPress release];
    }   
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{    
    return YES;
}

- (IBAction)handleGesture{
    NSLog(@"Got a gesture!");
}

我不认为我真的需要在我的视图控制器中使用 UILongPressGestureRecognizer。当我尝试完全在 MyViewController.xib 文件中创建它时,我使用 XCode 4.2 进行了以下操作

  • 在 xib 中的 UIToolBar 上拖动了一个 UILongPressRecognizer(附加到 MyViewController 中的工具栏)。
  • 将 UILongPressRecognizer 的委托属性设置为文件的所有者
  • 将选择器属性设置为 MyViewController 的 handleGesture 消息。

当我在模拟器中运行应用程序时,控制台中出现以下 gdb 错误:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance

显然 UILongPressGestureRecognizer initWithCoder: 没有被执行,但我想知道在 xib 文件中设置 UIGestureRecognizer 的正确方法是什么。 XCode 在那里有手势,我已经将它连接到一个视图。我看不出我出了什么问题。我在 UIGestureRecognizer 上看到的所有链接,包括 Apple 的 UIGestureRecognizer's class reference 始终使用代码中的 UIGestureRecognizer。我还没有看到只使用 xib 文件来配置它的示例。

我不太关心这个问题,因为我可以使用 ViewController 中的代码来处理它,但我很困惑为什么 XCode 允许在 UILongPressGestureRecognizer 和/或 UIGestureRecognizer 不符合的情况下在笔尖中添加手势识别器NSCoding 协议和 initWithCoder 将被调用。我的直觉说问题出在我身上,而不是 Apple,但我很想知道出了什么问题。

谢谢!

更新

我似乎只在使用 UISplitViewController 时在测试中看到这种行为。如果我创建一个基于 ViewController 的项目, UIGestureRecognizer 会按预期工作。如果我在 UISplitViewController 应用程序的 DetailView 上添加一个手势识别器,我会遇到这样的崩溃:

2011-11-03 10:17:55.873 GestureSplitViewTest[1143:b603] -[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance 0x59696b0
2011-11-03 10:17:55.877 GestureSplitViewTest[1143:b603] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance 0x59696b0'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x011b15a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x01305313 objc_exception_throw + 44
    2   CoreFoundation                      0x011b30bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x01122966 ___forwarding___ + 966
    4   CoreFoundation                      0x01122522 _CF_forwarding_prep_0 + 50
    5   UIKit                               0x002fe9fd UINibDecoderDecodeObjectForValue + 2592
    6   UIKit                               0x002fe2f5 UINibDecoderDecodeObjectForValue + 792
    7   UIKit                               0x002ff6ac -[UINibDecoder decodeObjectForKey:] + 398
    8   UIKit                               0x00214979 -[UIRuntimeConnection initWithCoder:] + 212
    9   UIKit                               0x003d34a8 -[UIRuntimeOutletCollectionConnection initWithCoder:] + 64
    10  UIKit                               0x002fe9fd UINibDecoderDecodeObjectForValue + 2592
    11  UIKit                               0x002fe2f5 UINibDecoderDecodeObjectForValue + 792
    12  UIKit                               0x002ff6ac -[UINibDecoder decodeObjectForKey:] + 398
    13  UIKit                               0x00213c36 -[UINib instantiateWithOwner:options:] + 804
    14  UIKit                               0x00215ab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
    15  UIKit                               0x000cb628 -[UIViewController _loadViewFromNibNamed:bundle:] + 70
    16  UIKit                               0x000c9134 -[UIViewController loadView] + 120
    17  UIKit                               0x000c900e -[UIViewController view] + 56
    18  UIKit                               0x000c7482 -[UIViewController contentScrollView] + 42
    19  UIKit                               0x000d7f25 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
    20  UIKit                               0x000d6555 -[UINavigationController _layoutViewController:] + 43
    21  UIKit                               0x000d7870 -[UINavigationController _startTransition:fromViewController:toViewController:] + 524
    22  UIKit                               0x000d232a -[UINavigationController _startDeferredTransitionIfNeeded] + 266
    23  UIKit                               0x001ed2e9 -[UILayoutContainerView layoutSubviews] + 226
    24  QuartzCore                          0x01888a5a -[CALayer layoutSublayers] + 181
    25  QuartzCore                          0x0188addc CALayerLayoutIfNeeded + 220
    26  QuartzCore                          0x018300b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
    27  QuartzCore                          0x01831294 _ZN2CA11Transaction6commitEv + 292
    28  UIKit                               0x0001b9c9 -[UIApplication _reportAppLaunchFinished] + 39
    29  UIKit                               0x0001be83 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 690
    30  UIKit                               0x00026617 -[UIApplication handleEvent:withNewEvent:] + 1533
    31  UIKit                               0x0001eabf -[UIApplication sendEvent:] + 71
    32  UIKit                               0x00023f2e _UIApplicationHandleEvent + 7576
    33  GraphicsServices                    0x00eb2992 PurpleEventCallback + 1550
    34  CoreFoundation                      0x01192944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    35  CoreFoundation                      0x010f2cf7 __CFRunLoopDoSource1 + 215
    36  CoreFoundation                      0x010eff83 __CFRunLoopRun + 979
    37  CoreFoundation                      0x010ef840 CFRunLoopRunSpecific + 208
    38  CoreFoundation                      0x010ef761 CFRunLoopRunInMode + 97
    39  UIKit                               0x0001b7d2 -[UIApplication _run] + 623
    40  UIKit                               0x00027c93 UIApplicationMain + 1160
    41  GestureSplitViewTest                0x0000234a main + 170
    42  GestureSplitViewTest                0x00002295 start + 53
)
terminate called throwing an exceptionsharedlibrary apply-load-rules all
Current language:  auto; currently objective-c
(gdb)

【问题讨论】:

  • 感谢这个问题,我遇到了同样的问题。有人提出雷达问题吗?

标签: ios uisplitviewcontroller xib uigesturerecognizer nib


【解决方案1】:

您确定您没有使用 iOS 4.3 SDK 而不是 iOS 5 SDK?

我花了 30 分钟才发现我使用了错误的 SDK。

【讨论】:

  • 我做了一个快速测试并确认你是对的。该应用程序使用 5.0 SDK 而不是 4.3 SDK 加载 UISplitViewController,并且无论仅使用 UIViewController 的常规子类,它都能正常工作。
【解决方案2】:

只需要放置UILongPressRecognizer,然后设置一个IBAction,比如

In H: -(IBAction)LongPress;
In M: -(IBAction)LongPress {
   NSLog(@"Good!");
}

最后将它连接到 UILongPressRecognizer。完毕! 经过测试并且可以工作。

希望这会有所帮助!

【讨论】:

  • 我用一个空项目再次尝试了这个,它就像你说的那样工作。我通过在笔尖中拖动 UIToolBar 添加了一个 UILongPressGestureRecognizer 并将其连接到我的 ViewController 中的 IBAction 函数,它按预期工作。我将深入研究我的另一个项目,试图弄清楚发生了什么,但我认为它只是按预期工作。希望很快。
  • 使用新知识修改了问题,该问题出现在基于 UISplitViewController 的应用程序中。
【解决方案3】:

由于稍后分发,因此有人回答更改 SDK 版本不是一个好主意。它无法安装在没有 5.0 SDK 的设备上。

代替那个不要在xib中添加它,而不是那个写代码。这是滑动手势示例代码

在初始化视图时将这部分代码写在某处,例如初始化

UISwipeGestureRecognizer *_swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
[_swipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[_swipeGestureRecognizer setNumberOfTouchesRequired:1];
[self addGestureRecognizer:_swipeGestureRecognizer];

还要写这个来处理手势动作

- (void)swipe:(id)sender { ... }

【讨论】:

    猜你喜欢
    • 2012-07-07
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多