Почему создание подкласса UIGestureRecognizer в перо вызывает сбой с использованием UISplitViewController - PullRequest
4 голосов
/ 02 ноября 2011

Меня заинтересовало использование подкласса UIGestureRecognizer (UILongPressGestureRecognizer) в подклассе ViewController, который у меня был. Мой ViewController имеет UIToolBar, и программно я могу создать экземпляр UILongPressGestureRecognizer, присоединенный к UIToolBar, и все будет работать. Мой 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 в моем View Controller. Когда я попытался создать его полностью в файле MyViewController.xib, я сделал следующее, используя XCode 4.2

  • Перетянул UILongPressRecognizer на мой UIToolBar в XIB (прикреплен к панели инструментов в MyViewController).
  • Установить свойство делегата UILongPressRecognizer владельцем файла
  • Установите свойство селектора для сообщения handleGesture MyViewController.

Когда я запускаю приложение в симуляторе, происходит сбой, который приводит к следующей ошибке GDB в консоли:

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

Очевидно, что UILongPressGestureRecognizer initWithCoder: не реализован, но мне интересно, как правильно настроить UIGestureRecognizer в xib-файле. У XCode есть жесты, и я связал это с представлением. Я не вижу, что я иду не так. Все ссылки, которые я видел на UIGestureRecognizer, включая ссылку на класс Apple *1021* UIGestureRecognizer *1021*, всегда используют UIGestureRecognizer из кода. Я не видел пример использования только xib-файла для его настройки.

Я не слишком обеспокоен этой проблемой, потому что я могу обработать ее с помощью кода в ViewController, но я запутался, почему XCode позволяет добавлять распознаватели жестов в кончик, если UILongPressGestureRecognizer и / или UIGestureRecognizer не соответствуют протокол NSCoding и initWithCoder будут вызваны. Моя интуиция говорит, что проблема моя, а не Apple, но я бы хотел понять, что происходит не так.

Спасибо!

Обновление

Кажется, я вижу это поведение только при тестировании, когда использую UISplitViewController. Если я создаю проект на основе ViewController, UIGestureRecognizer работает как положено. Если я добавляю Gesture Recognizer в DetailView приложения UISplitViewController, я получаю сбой, подобный этому:

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)

Ответы [ 3 ]

4 голосов
/ 04 ноября 2011

Вы убедились, что не используете iOS 4.3 SDK вместо iOS 5 SDK?

Я потратил добрых 30 минут, чтобы узнать, что я использую неправильный SDK.

1 голос
/ 07 августа 2012

Не стоит менять версию SDK, поскольку кто-то ответил из-за более позднего распространения.Он не сможет быть установлен на устройствах без 5.0 SDK.

Вместо этого не добавляйте его в xib вместо того, чтобы писать код.Вот пример кода жеста смахивания

Запишите эту часть кода где-нибудь при инициализации представления, например, Init

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

, а также напишите это для обработки действия жеста

- (void)swipe:(id)sender { ... }
1 голос
/ 03 ноября 2011

Требуется только разместить UILongPressRecognizer, а затем настроить IBAction, например

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

Последнее подключение к UILongPressRecognizer. Готово! Проверено и работает.

Надеюсь, это поможет!

...