【问题标题】:How do I set up an UIScreenEdgePanGestureRecognizer using Interface Builder?如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?
【发布时间】: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) 中仍未解决

【问题讨论】:

    标签: ios objective-c xcode interface-builder


    【解决方案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 错误,最好以编程方式添加它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-26
            • 1970-01-01
            相关资源
            最近更新 更多