如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?
Posted
技术标签:
【中文标题】如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?【英文标题】:How do I set up an UIScreenEdgePanGestureRecognizer using Interface Builder? 【发布时间】:2014-10-08 12:32:12 【问题描述】:当我使用 Interface Builder 将 UIScreenEdgePanGestureRecognizer
添加到我的视图控制器时,我无法让 UIScreenEdgePanGestureRecognizer
工作,所以我在这里询问我是否做错了什么或者是否存在错误Xcode。
以下是重现的步骤:
使用适用于 ios 的“单一视图应用程序”模板创建一个新的 Xcode 项目。 通过从 Interface Builder 的对象库中拖动一个UIView
到主视图控制器中
通过从 Interface Builder 的对象库中拖动一个 UIScreenEdgePanGestureRecognizer
到视图中
确保已启用手势识别器并选择边缘:
打开ViewController
类的助手编辑器,然后按住Ctrl 键从UIScreenEdgePanGestureRecognizer
拖动到ViewController
的实现块以创建一个新的IBAction
` 在动作的方法体中添加一个断点来测试边缘平移手势是否被识别
生成的代码如下:
如果我在我的设备(运行 iOS 8.02 的 iPhone 6)上运行应用程序,当我进行边缘滑动时断点不会被命中。
我有什么遗漏吗?
更新:这是在 2014 年 10 月 8 日向 Apple (rdar://18582306) 提交的错误,但在 Xcode 6.4 (6E35b) 中仍未解决
【问题讨论】:
【参考方案1】:我设置了一个项目来测试您的问题,并发现了与您相同的问题。以下是我设置的测试场景:
我完全按照你的做法使用 Interface Builder 来构建屏幕边缘手势。我的代码中唯一的区别是我在选择器中放了一行代码,这样调试器就会停下来。调试器未能完全按照您的发现停止。
-(void)handlePan:(id)sender
NSString *test = @"";
然后,我使用 Interface Builder 在同一视图上使用捏合手势创建了一个额外的手势,并且我能够让调试器在该选择器内停止。所以 Interface Builder 似乎能够正确构建其他手势。
然后我使用以下代码手动创建了屏幕边缘手势,它按预期工作。在 ViewController.h 文件中,我包含了 UIGestureRecognizerDelegate。
@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
@end
在 ViewController.m 文件中,我手动实现了手势。
#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
我最终得出了与您相同的结论 - Interface Builder 的 UIScreenEdgePanGestureRecognizer 实现似乎有问题。
【讨论】:
想补充一点,我在模拟器和我的设备上对此进行了测试,结果相同 - 对 IB 实现的手势没有响应。 感谢您花时间对此进行测试。我现在已经向 Apple 提交了错误报告:openradar.io/18582306 我已将此标记为已接受的答案,因为它确认我没有做任何不正确的事情,并且 Xcode 的行为不符合预期。 @zisoft 我正在使用 6.0.1 (6A317) 这里不需要设置委托..有吗?【参考方案2】:我已经在 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
得到一个错误
【讨论】:
【参考方案3】:它可以被认为是一个错误,但实际上,这里有一些有用的东西:
“创建屏幕边缘平移手势识别器后,在将手势识别器附加到您的视图之前,为边缘属性分配一个适当的值。”
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIScreenEdgePanGestureRecognizer_class/index.html
这个要求只适用于UIScreenEdgePanGestureRecognizer,所以我认为这就是Xcode出错的原因,它必须按照正常的顺序来实现,alloc->init->attach->set value。它适用于所有其他 GestureRecongnizer,但不适用于 UIScreenEdgePanGestureRecognizer。
【讨论】:
你引用的那一行是指作者已经在截图中设置的边缘值(上、左、右、下)【参考方案4】: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)")
【讨论】:
【参考方案5】:要确保多个手势识别器可以协同工作,您必须实现方法shouldRecognizeSimultaneouslyWithGestureRecognizer
并返回true:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool
return true
对不起,Swift 代码,但你应该明白了。
即使您使用单个手势识别器也必须实现此方法,因为视图可以有自己的(系统)识别器,例如MKMapView
。
【讨论】:
不幸的是,实现gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
委托方法并使ViewController
成为UIScreenEdgePanGestureRecognizer
的委托没有任何区别。仍然没有检测到边缘平移。常规 UIPanGestureRecognizer
工作正常。认为我可能会提出错误报告。【参考方案6】:
Xcode 6.4 的界面生成器和 Swift 中似乎存在错误。另外,Thomas LIU 的回答也是正确的:似乎需要在代码中设置 .edge 属性,而不是使用 Interface Builder。
虽然 IB 中有边缘复选框,但它们似乎被忽略了。
我是这样解决的: 按住 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")
【讨论】:
【参考方案7】:长期面临同样的问题。它是一个 xcode 错误,最好以编程方式添加它。
【讨论】:
以上是关于如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Interface Builder 中使用自定义 UIButton 类别?
如何在 Xcode 9 中将 Autoresizing 应用于 Interface Builder?
Interface Builder 是如何知道 UIViewController 的视图的?
如何在 Interface Builder 中获取 iPhone,而不是 iPad 视图
Interface Builder 将控制出口设置为零——为啥?
如何在 Interface Builder 中的 UIViewController 中自动调整 UIView Outlet 的大小