Как настроить UIScreenEdgePanGestureRecognizer с помощью построителя интерфейса?

Я не могу сделать UIScreenEdgePanGestureRecognizer для работы, когда я создаю, когда я добавляю его в контроллер вида с помощью Interface Builder, поэтому я прошу здесь установить, делаю ли я что-то неправильно или есть ошибка в Xcode.

вот шаги для воспроизведения:

  • создайте новый проект Xcode, используя шаблон "одно приложение просмотра" для iOS.
  • добавить UIView к контроллеру главного вида, перетащив один из библиотеки объектов в интерфейсе Строитель!--13-->
  • добавить UIScreenEdgePanGestureRecognizer в представление, перетащив один из библиотеки объектов в Interface Builder
  • убедитесь, что распознаватель жестов включен и выбрано ребро:

enter image description here

  • откройте помощник редактора ViewController class и ctrl-перетащите из UIScreenEdgePanGestureRecognizer до ViewControllerблок реализации для создания нового IBAction 'Добавьте точку останова в тело метода действия, чтобы проверить, является ли жест edge pan узнается

результирующий код выглядит следующим образом:

Code example

если я запускаю приложение на своем устройстве (iPhone 6 под управлением iOS 8.02), точка останова не попадает, когда я делаю красть.

Я что-то упускаю?

обновление: это было подано как ошибка с Apple (rdar: / / 18582306) на 08-Oct-2014 и до сих пор не решена в Xcode 6.4 (6E35b)

7 ответов


Я создал проект, чтобы проверить ваш вопрос и нашел ту же проблему, что и вы. Вот сценарии, которые я настроил для тестирования:

  • Я сделал точно так же, как вы, используя Interface Builder, чтобы построить жест края экрана. Единственное отличие в моем коде заключается в том, что я помещаю строку кода в селектор, чтобы отладчику было на чем остановиться. Отладчику не удалось остановиться точно так, как вы нашли.

    -(void)handlePan:(id)sender
    {
        NSString *test = @"";
    }
    
  • Я создал дополнительный жест с помощью жеста pinch на том же представлении с помощью Interface Builder, и я смог заставить отладчик остановиться в этом селекторе. Таким образом, Interface Builder, похоже, может правильно создавать другие жесты.

  • затем я создал жест края экрана вручную, используя следующий код, и он работал так, как ожидалось.

в ViewController.H файл I включал UIGestureRecognizerDelegate.

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
@end

в ViewController.файл м я реализован жест вручную.

#import "ViewController.h"

@interface ViewController ()

-(void)handlePan:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad 
{
    [super viewDidLoad];
    UIScreenEdgePanGestureRecognizer *pan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
                                                                                              action:@selector(handlePan:)];
    [pan setEdges:UIRectEdgeLeft];
    [pan setDelegate:self];
    [self.view addGestureRecognizer:pan];
}

-(void)handlePan:(id)sender
{
    NSString *test = @"";
}

@end

Я закончил с тем же выводом, что и Вы - кажется, что-то не так с реализацией построителя интерфейса UIScreenEdgePanGestureRecognizer.


Это можно рассматривать как ошибку, но на самом деле, вот что полезно:

" после создания распознавателя жестов края экрана назначьте соответствующее значение свойству Edge перед присоединением распознавателя жестов к вашему представлению."

https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIScreenEdgePanGestureRecognizer_class/index.html

Это требование применяется только к UIScreenEdgePanGestureRecognizer, поэтому я думаю, что именно поэтому Xcode делает это неправильно, он должен быть реализован как обычная последовательность, alloc->init->attach->set value. Он будет работать со всеми другими GestureRecongnizer, но не UIScreenEdgePanGestureRecognizer.


Я пробовал это в Xcode 7.0 Beta 4 (7A165t), и это все еще ошибка. Добавление распознавателя жестов края экрана через Interface Builder не вызывает ссылочный IBAction, однако добавление его программно, как это работает отлично:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let edgeGestureRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: "userSwipedFromEdge:")
        edgeGestureRecognizer.edges = UIRectEdge.Left
        edgeGestureRecognizer.delegate = self
        self.view.addGestureRecognizer(edgeGestureRecognizer)
    }

    func userSwipedFromEdge(sender: UIScreenEdgePanGestureRecognizer) {
        if sender.edges == UIRectEdge.Left {
            print("It works!")
        }
    }
}

подсказка: не забудьте добавить UIGestureRecognizerDelegate протокол к классу. В противном случае вы получите сообщение об ошибке edgeGestureRecognizer.delegate = self


чтобы убедиться, что несколько распознавателей жестов могут работать вместе, вы должны реализовать метод shouldRecognizeSimultaneouslyWithGestureRecognizer и возвращать true:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

извините за Swift-код, но вы должны уловить идею.

этот метод должен быть реализован, даже если вы используете один жест распознаватель потому что вид может иметь свои собственные (системные) распознаватели, такие как MKMapView.


Xcode не всегда хороший сосед. Извиняюсь.

override func viewDidLoad() {
    super.viewDidLoad()

    let panGesture = UIScreenEdgePanGestureRecognizer(target: self, action: "panAction:")
    panGesture.edges = .Left
    view.addGestureRecognizer(panGesture)
}


func panAction(sender: UIScreenEdgePanGestureRecognizer) {
    let translation = sender.translationInView(sender.view!)

    println("Trans:\(translation)")
}

похоже, что в Xcode 6.4 есть ошибка в построителе интерфейса и Swift. Кроме того, ответ Томаса Лю также был правильным: кажется, необходимо установить .свойство edge в коде, а не с помощью Interface Builder.

хотя в IB есть флажки edge, они, похоже, игнорируются.

я решил это таким образом: Ctrl-перетащите из распознавателя жестов в класс viewController, чтобы создать IBOutlet:

class ViewController: UIViewController {
    @IBOutlet var leftEdgeGestureRecognizer: UIScreenEdgePanGestureRecognizer!

тогда, в метод viewDidLoad:

leftEdgeGestureRecognizer.edges = .Left

и, наконец, ctrl-перетащите из распознавателя, чтобы создать IBAction

@IBAction func swipeFromLeft(sender: AnyObject) {
        print("===> Swipe from left edge.\n")
}

сталкивается с той же проблемой от long. Его ошибка xcode, лучше добавить его программно.