Как настроить UIScreenEdgePanGestureRecognizer с помощью построителя интерфейса?
Я не могу сделать UIScreenEdgePanGestureRecognizer
для работы, когда я создаю, когда я добавляю его в контроллер вида с помощью Interface Builder, поэтому я прошу здесь установить, делаю ли я что-то неправильно или есть ошибка в Xcode.
вот шаги для воспроизведения:
- создайте новый проект Xcode, используя шаблон "одно приложение просмотра" для iOS.
- добавить
UIView
к контроллеру главного вида, перетащив один из библиотеки объектов в интерфейсе Строитель!--13--> - добавить
UIScreenEdgePanGestureRecognizer
в представление, перетащив один из библиотеки объектов в Interface Builder - убедитесь, что распознаватель жестов включен и выбрано ребро:
- откройте помощник редактора
ViewController
class и ctrl-перетащите изUIScreenEdgePanGestureRecognizer
доViewController
блок реализации для создания новогоIBAction
'Добавьте точку останова в тело метода действия, чтобы проверить, является ли жест edge pan узнается
результирующий код выглядит следующим образом:
если я запускаю приложение на своем устройстве (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 перед присоединением распознавателя жестов к вашему представлению."
Это требование применяется только к 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")
}