Ios UINavigationController交互弹出手势不工作?

Ios UINavigationController交互弹出手势不工作?,ios,uinavigationcontroller,ios7,gesture,Ios,Uinavigationcontroller,Ios7,Gesture,因此,我的iOS 7应用程序内置了一个导航控制器。标题视图可见,后退按钮和导航栏也可见。出于某种原因,交互式弹出手势(从左边缘滑动)不起作用。什么也没发生。当我记录手势时,它不是零。要启用此功能,我需要做什么特殊的事情吗?是什么导致它无法工作?呃,看起来我只需要设置手势代理并实现以下操作: -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestu

因此,我的iOS 7应用程序内置了一个导航控制器。标题视图可见,后退按钮和导航栏也可见。出于某种原因,交互式弹出手势(从左边缘滑动)不起作用。什么也没发生。当我记录手势时,它不是零。要启用此功能,我需要做什么特殊的事情吗?是什么导致它无法工作?

呃,看起来我只需要设置手势代理并实现以下操作:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    return YES;

}

您可以将这一行放入viewDidLoad方法中

self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
self.navigationController.interactiveepgpgestureerecognizer.delegate=(id)self;
看看这个和评论。您只需将导航控制器的交互式pop手势识别器的委托设置为
nil

self.navigationController.interactivePopGestureRecognizer.delegate = nil;

将它设置为一个casted self to
id
也可以,因为协议中的所有方法都是可选的,但我认为在这种情况下,将委托设置为
nil
更合适。

更有效的答案是Aaron和lojals

首先自定义导航控制器,然后将此代码放入类中

在ViewDidload中,放置以下行:

self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;

我发现,当使用自定义后退按钮时,交互式弹出手势会停止工作(我的理解是苹果无法预见自定义后退按钮的行为,所以他们会禁用该手势)

要解决此问题,正如前面提到的其他问题一样,您可以将
interactiveepgestureerecognizer.delegate
属性设置为
nil

在Swift中,通过为
UINavigationController
添加如下扩展,可以在整个应用程序中轻松实现这一点:

更新的答案

self.navigationController?.navigationBar.isHidden = true
似乎将委托设置为
nil
会导致应用程序UI在某些情况下冻结(例如,当用户在导航堆栈的俯视图控制器上向左或向右滑动时)

由于
gestureRecognitizerShouldBegin
委托方法无法在扩展中处理,因此子类化
UINavigationController
似乎是最好的解决方案:

class NavigationController: UINavigationController, UIGestureRecognizerDelegate {

    /// Custom back buttons disable the interactive pop animation
    /// To enable it back we set the recognizer to `self`
    override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }

}

在Swift 4中,我的视图控制器中有一个UITableView,我通过以下方法解决了此问题:

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.interactivePopGestureRecognizer?.delegate=nil
}

也许有人会觉得这很有帮助

如果要隐藏导航栏,但使用正常的滑动手势返回和其他导航控制器功能,则应使用:(导航栏

如果要禁用导航栏(隐藏导航栏,禁用向后滑动),但要推送viewcontroller,则应使用:(isNavigationBarHidden

更新日期:2018年12月7日:

推荐方式:

如果您的第一个控制器使用隐藏的导航栏,但下一个孩子使用导航栏,当您返回到基本视图控制器时,您将看到一个黑色的过渡栏代替导航栏。如果您在第一个viewcontroller(父视图)中使用,这将非常容易修复:


一般在整个应用程序中添加交互式弹出手势。

XCODE:9.0,Swift:4.0

最好在AppDelegate.swift中创建UINavigationController

  • 创建导航控制器
  • 实施
    UIgestureRecognitizerDelegate
  • 在application didFinishLaunchingWithOptions函数中实例化UINavigationController
  • 额外步骤,在application didFinishLaunchingWithOptions功能中将控制器添加到导航控制器
  • 实施味觉识别器,将以下代码添加到AppDelegate.swift


  • 注意:请参阅本节中的其他帖子,了解两者之间的区别

    self.navigationController?.navigationBar.isHidden=true
    


    我的答案基于Eneko的答案,但仅使用UINavigationController上的扩展,并在Swift 5中工作:

    extension UINavigationController: UIGestureRecognizerDelegate {
    
        override open func viewDidLoad() {
            super.viewDidLoad()
            interactivePopGestureRecognizer?.delegate = self
        }
    
        public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return viewControllers.count > 1
        }
    }
    

    如果你觉得你已经尝试了所有的解决方案,并且伸了伸你的头,那么你是在正确的地方

    Goto simulator > Window > Enable Show Device Bezels
    


    现在,我尝试模拟“向后滑动”的手势。

    我只在ViewDiDapperthis“正常工作”时才成功,但不久之后导致了非常奇怪的问题,甚至冻结了应用程序(使用iOS 8测试,设备)。我检查了这个问题,但非常令人毛骨悚然,当我修复这个问题时,如果用户滑到一半,然后回来,我会看到下一个控制器与上一个视图控制器重叠。我看到上一个视图控制器,下一个重叠的视图控制器像透明玻璃一样透明。所以用户恰好被锁定在这个状态。任何想法。这是View在处理问题时出现/将出现的情况。这似乎可行,但在某些情况下,它会冻结应用程序。我认为在按下视图控制器时触发交互式弹出手势时会发生这种情况。更安全的方法是将
    UINavigationController
    子类化。在子类中,将interactivePopGestureRecognizer.delegate设置为self,并防止在推送新视图控制器时识别交互式pop手势。事实上,我也发现该问题似乎只影响导航控制器堆栈的俯视图控制器。我已经用基于子类化的不同解决方案更新了我的答案。@Eneko Alonso完美!正如您所说,若用户向左或向右滑动,然后点击按钮,那个么按下视图控制器就会出现故障。子类化100%修复了问题@EnekoAlonso当我将导航栏设置为隐藏时,我也遇到了类似的问题。我失去了向后滑动的功能。你有什么办法可以帮忙的吗?为了清楚起见,我发布了这个问题:IOS 13对我不起作用。你有什么建议吗?使用ios 13.1这太愚蠢了,但它确实有效!为什么苹果改变了这一点?。。。谢谢!非常感谢软件设计师✅.
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden(true, animated: animated)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.navigationController?.setNavigationBarHidden(false, animated: animated)
    }
    
    // I created a global variable, however not necessarily you will be doing this way
    var nvc: UINavigationController!
    
    class AppDelegate: UIResponder, UIApplicationDelegate, UIGestureRecognizerDelegate {
    
    nvc=UINavigationController()
    
    // For interactive pop gesture
    nvc.navigationBar.isHidden=true
    nvc?.interactivePopGestureRecognizer?.delegate=self
    
    window=UIWindow()
    window?.rootViewController=nvc
    window?.makeKeyAndVisible()
    
    // BaseViewController is sample controller i created with xib
    nvc.pushViewController(BaseViewController(), animated: true)
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    
    self.navigationController?.navigationBar.isHidden=true
    
    self.navigationController?.isNavigationBarHidden = true
    
    extension UINavigationController: UIGestureRecognizerDelegate {
    
        override open func viewDidLoad() {
            super.viewDidLoad()
            interactivePopGestureRecognizer?.delegate = self
        }
    
        public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return viewControllers.count > 1
        }
    }
    
    Goto simulator > Window > Enable Show Device Bezels