xcode 如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26256985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:48:41  来源:igfitidea点击:

How do I set up an UIScreenEdgePanGestureRecognizer using Interface Builder?

iosobjective-cxcodeinterface-builder

提问by j b

I can't get UIScreenEdgePanGestureRecognizerto work when I create when I add it to my view controller using Interface Builder, so I'm asking here to establish whether I'm doing something wrong or if there is a bug in Xcode.

UIScreenEdgePanGestureRecognizer当我使用 Interface Builder 将它添加到我的视图控制器时,我无法开始工作,所以我在这里要求确定我是否做错了什么,或者 Xcode 中是否存在错误。

Here are the steps to reproduce:

以下是重现的步骤:

  • Create a new Xcode project using the "Single View Application" template for iOS.
  • Add a UIViewto the main view controller by dragging one from the Object Library in Interface Builder
  • Add a UIScreenEdgePanGestureRecognizerto the view by dragging one from the Object Library in Interface Builder
  • Ensure that the gesture recogniser is enabled and that an edge is selected:
  • 使用适用于 iOS 的“单一视图应用程序”模板创建一个新的 Xcode 项目。
  • UIView通过从 Interface Builder 中的对象库中拖动一个来将一个添加到主视图控制器
  • UIScreenEdgePanGestureRecognizer通过从 Interface Builder 中的对象库中拖动一个来将一个添加到视图中
  • 确保启用了手势识别器并选择了一条边:

enter image description here

在此处输入图片说明

  • Open the assistant editor for the ViewControllerclass and ctrl-drag from the UIScreenEdgePanGestureRecognizerto the ViewController's implementation block to create a new IBAction` Add a breakpoint in the action's method body to test if the edge pan gesture is being recognized
  • 打开类的辅助编辑器,ViewController按住ctrl键拖拽UIScreenEdgePanGestureRecognizerViewController实现块新建一个IBAction`在action方法体中添加断点,测试是否可以识别边缘平移手势

The resulting code is as follows:

结果代码如下:

Code example

代码示例

If I run the application on my device (iPhone 6 running iOS 8.02) the breakpoint does not get hit when I do an edge swipe.

如果我在我的设备(运行 iOS 8.02 的 iPhone 6)上运行该应用程序,当我执行边缘滑动时,断点不会被击中。

Is there something I'm missing?

有什么我想念的吗?

UPDATE: this was filed as a bug with Apple (rdar://18582306) on 08-Oct-2014 and still isn't resolved in Xcode 6.4 (6E35b)

更新:这是在 2014 年 10 月 8 日作为 Apple (rdar://18582306) 的错误提交的,但在 Xcode 6.4 (6E35b) 中仍未解决

回答by sunergeos

I set up a project to test your question and found the same issue you did. Here are the scenarios I set up to test:

我建立了一个项目来测试您的问题,并发现了您所做的相同问题。以下是我为测试而设置的场景:

  • I did exactly as you did, using Interface Builder, to build the screen edge gesture. The only difference in my code is that I put a line of code in the selector so the debugger would have something to stop on. The debugger failed to halt exactly as you found.

    -(void)handlePan:(id)sender
    {
        NSString *test = @"";
    }
    
  • I then created an additional gesture using the pinch gesture on the same view using Interface Builder and I was able to get the debugger to halt within that selector. So Interface Builder seems to be able to build other gestures correctly.

  • I then created the screen edge gesture manually using the following code and it worked as expected.
  • 我和你做的完全一样,使用界面生成器来构建屏幕边缘手势。我的代码的唯一区别是我在选择器中放置了一行代码,以便调试器可以停止。调试器未能完全按照您的发现停止。

    -(void)handlePan:(id)sender
    {
        NSString *test = @"";
    }
    
  • 然后,我使用 Interface Builder 在同一视图上使用捏合手势创建了一个额外的手势,并且我能够让调试器在该选择器内停止。因此 Interface Builder 似乎能够正确构建其他手势。

  • 然后我使用以下代码手动创建了屏幕边缘手势,它按预期工作。

In the ViewController.h file I included the UIGestureRecognizerDelegate.

在 ViewController.h 文件中,我包含了 UIGestureRecognizerDelegate。

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
@end

In the ViewController.m file I implemented the gesture manually.

在 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

I ended up with the same conclusion you did - there seems to be something wrong with the Interface Builder's implementation of the UIScreenEdgePanGestureRecognizer.

我最终得到了与您相同的结论 - 界面生成器对 UIScreenEdgePanGestureRecognizer 的实现似乎有问题。

回答by Peter

I have tried it in Xcode 7.0 Beta 4 (7A165t) and it's still a bug. Adding the Screen Edge Pan Gesture Recognizer via Interface Builder doesn't call the referenced IBAction, however adding it programmatically like this works fine:

我已经在 Xcode 7.0 Beta 4 (7A165t) 中尝试过它,但它仍然是一个错误。通过 Interface Builder 添加 Screen Edge Pan Gesture Recognizer 不会调用引用的 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!")
        }
    }
}

Hint:Don't forget to add the UIGestureRecognizerDelegateprotocol to your class. Otherwise you'll get an error at edgeGestureRecognizer.delegate = self

提示:不要忘记将UIGestureRecognizerDelegate协议添加到您的类中。否则你会得到一个错误edgeGestureRecognizer.delegate = self

回答by Thomas LIU

It can be considered as a bug, but actually, here is something useful:

它可以被视为一个错误,但实际上,这里有一些有用的东西:

"After creating a screen edge pan gesture recognizer, assign an appropriate value to the edges property before attaching the gesture recognizer to your view."

“创建屏幕边缘平移手势识别器后,在将手势识别器附加到您的视图之前,为边缘属性分配适当的值。”

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

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

This requirement only apply to UIScreenEdgePanGestureRecognizer, so I think that's why Xcode make it wrong, it must be implemented as the normal sequence, alloc->init->attach->set value. It will work to all other GestureRecongnizer but not UIScreenEdgePanGestureRecognizer.

这个要求只适用于UIScreenEdgePanGestureRecognizer,所以我认为这就是Xcode出错的原因,它必须按照正常顺序来实现,alloc->init->attach->set value。它适用于所有其他 GestureRecongnizer,但不适用于 UIScreenEdgePanGestureRecognizer。

回答by Zelko

Xcode isn't always a good neighbor. Sorry.

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)")
}

回答by zisoft

To make sure that multiple gesture recognizers can work together you have to implement the method shouldRecognizeSimultaneouslyWithGestureRecognizerand return true:

要确保多个手势识别器可以一起工作,您必须实现该方法shouldRecognizeSimultaneouslyWithGestureRecognizer并返回 true:

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

Sorry for the Swift code but you should get the idea.

对不起 Swift 代码,但你应该明白这个想法。

This method must be implemented even if you are using a single gesture recognizer because the view can have its own (system) recognizers, such as MKMapView.

即使您使用单个手势识别器,也必须实现此方法,因为视图可以拥有自己的(系统)识别器,例如MKMapView.

回答by drtofu

It seems that there is a bug in Xcode 6.4's interface builder and Swift. Also, Thomas LIU's answer was also correct: it seems to be necessary to set the .edge property in code, rather than with Interface Builder.

Xcode 6.4 的界面构建器和Swift 中似乎存在一个错误。此外,Thomas LIU 的回答也是正确的:似乎有必要在代码中设置 .edge 属性,而不是使用 Interface Builder。

Even though there are edge checkboxes in IB, they seem to be ignored.

即使 IB 中有边缘复选框,它们似乎也被忽略了。

I solved it this way: Ctrl-drag from the gesture recognizer to the viewController class to create an IBOutlet:

我是这样解决的:按住 Ctrl 键从手势识别器拖动到 viewController 类以创建一个 IBOutlet:

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

then, in viewDidLoad:

然后,在 viewDidLoad 中:

leftEdgeGestureRecognizer.edges = .Left

and finally, ctrl-drag from the recognizer to create an IBAction

最后,从识别器按住 ctrl-drag 来创建一个 IBAction

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

回答by itsji10dra

Facing same issue from long. Its a xcode bug, its better to add it programmatically.

长期面临同样的问题。它是一个 xcode 错误,最好以编程方式添加它。