UINavigationBar 中的 UIBarButtonItems 无法点击

UIBarButtonItems in UINavigationBar are unclickable

我的 UIBarButtonItems 似乎对点击没有任何反应。

我有一个连接到 TableViewController 的平移手势识别器,但是我已经确定在启用 panGestureRecognizer.cancelsTouchesInViewfalse 后这不会阻止它。

现在,导航控制器嵌入到我为管理滑出视图控制器而创建的 ContainerViewController 中,包括如下:

import UIKit

class InstructorSlideOutContainerViewController: SlideOutContainerViewController {

var isFromLogin:Bool?

override func viewDidLoad() {
    super.viewDidLoad()
    setLeftViewController(identifier: "InstructorSettingsTableViewController")
    setCenterViewController(identifier: "InstructorClassesTableViewController")
    (centerViewController as! InstructorClassesTableViewController).delegate = self
    (centerViewController as! InstructorClassesTableViewController).touchDelegate = self
    (centerViewController as! InstructorClassesTableViewController).isFromLogin = isFromLogin

    centerNavigationController = UINavigationController(rootViewController: centerViewController!)
    view.addSubview(centerNavigationController.view)
    addChildViewController(centerNavigationController)

    centerNavigationController.didMove(toParentViewController: self)

    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
    centerNavigationController.view.addGestureRecognizer(panGestureRecognizer)
}

class func getEntrySegueFromFBLogin() -> String {
    return "FBLoginToInstructorContainerSegue"
}

class func getEntrySegueFromLogin() -> String {
    return "LoginToInstructorContainerSegue"
}

class func getEntrySegueFromSignUp() -> String {
   return "LoginToInstructorContainerSegue"
}
}

它是广义的 ContainerViewController 的子类:

enum SlideOutState {
    case LeftPanelClosed
    case LeftPanelExpanded
}

import UIKit

protocol SlideOutContainerViewControllerDelegate {
    func toggleLeftPanel()
}

protocol InitializeViewControllers {
    func setLeftViewController(identifier: String)
    func setCenterViewController(identifier: String)
}

class SlideOutContainerViewController: UIViewController {

    var centerNavigationController: UINavigationController!
    var centerViewController: UIViewController?
    var currentState: SlideOutState = .LeftPanelClosed
    var leftViewController: UIViewController?
    var centerViewControllerIdentifer = ""
    let centerPanelExpandedOffset: CGFloat = 60
    var mainStoryboard:UIStoryboard?
    override func viewDidLoad() {
        super.viewDidLoad()
        mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    }

}

extension SlideOutContainerViewController: InitializeViewControllers {

    func setLeftViewController(identifier: String) {
        leftViewController = mainStoryboard?.instantiateViewController(withIdentifier: identifier)
    }

    func setCenterViewController(identifier: String) {
       centerViewController = mainStoryboard?.instantiateViewController(withIdentifier: identifier)
    }
}

extension SlideOutContainerViewController: SlideOutContainerViewControllerDelegate {
    func toggleLeftPanel(){
        let notAlreadyExpanded = (currentState != .LeftPanelExpanded)
        if notAlreadyExpanded {
            addChildSidePanelController(sidePanelController: leftViewController!)
        }
        animateLeftPanel(shouldExpand: notAlreadyExpanded)
    }

    func addChildSidePanelController(sidePanelController: UIViewController) {
        view.insertSubview(sidePanelController.view, at: 0)
        addChildViewController(sidePanelController)
        sidePanelController.didMove(toParentViewController: self)
    }

    func animateLeftPanel(shouldExpand: Bool){
        if shouldExpand {
            currentState = .LeftPanelExpanded
            animateCenterPanelXPosition(targetPosition: centerNavigationController.view.frame.width - centerPanelExpandedOffset)
        } else {
            animateCenterPanelXPosition(targetPosition: 0) {finished in
                self.currentState = .LeftPanelClosed
                self.leftViewController?.view.removeFromSuperview()
            }
        }
    }

    func animateCenterPanelXPosition(targetPosition: CGFloat, completion: ((Bool) -> Void)! = nil) {
        UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseOut, animations: {
            self.centerNavigationController.view.frame.origin.x = targetPosition
        }, completion: completion)
    }

    func showShadowForCenterViewController(shouldShowShadow: Bool) {
        if shouldShowShadow {
            centerNavigationController.view.layer.shadowOpacity = 0.8
        } else {
            centerNavigationController.view.layer.shadowOpacity = 0.0
        }
    }
}

// MARK: Gesture Recognizer

extension SlideOutContainerViewController {
    func handlePanGesture(_ recognizer: UIPanGestureRecognizer) -> Void {
        let gestureIsDraggingFromLeftToRight = recognizer.velocity(in: view).x > 0

        switch recognizer.state {
        case .began:
            if currentState == .LeftPanelClosed {
                if gestureIsDraggingFromLeftToRight {
                    addChildSidePanelController(sidePanelController: leftViewController!)
                }
                showShadowForCenterViewController(shouldShowShadow: true)
            }
        case .changed:
            if gestureIsDraggingFromLeftToRight || currentState == .LeftPanelExpanded {
                recognizer.view!.center.x = recognizer.view!.center.x + recognizer.translation(in: view).x
                recognizer.setTranslation(CGPoint.zero, in: view)
            }
        case .ended:
            if leftViewController != nil {
                let hasMovedMoreThanHalfway = recognizer.view!.center.x > view.bounds.size.width
                animateLeftPanel(shouldExpand: hasMovedMoreThanHalfway)
            }
        default:
            break
        }
    }
}

这是故事板的屏幕截图。

所以基本上一旦 Containerviewcontroller 加载,我就不能使用导航栏中的任何按钮。 TableViewController 中的触摸仍然被注册,似乎它只是 UINavigationBar 中的 UIBarButtonItems

我仔细检查了所有插座是否已连接,现在正在努力寻找其他解决方案...

提前致谢!!

EDIT:如果我删除嵌入式故事板 UINavigationController,我可以让按钮工作,但是我需要它,这样当从另一个 UINavigationController 转至 <Back 箭头未显示在 NavigationController 的顶部。

解决方案是使用模式转场转场到 viewcontroller,因为 containerviewcontroller 正在与 navigationcontroller 竞争并且需要声明它是自己的而不是简单地被推到导航堆栈。