UINavigationBar中的UIBarButtonItems是不可点击的

时间:2017-09-02 22:34:58

标签: ios swift uinavigationcontroller uikit uibarbuttonitem

我的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
        }
    }
}

这是故事板的截图。

picture 所以基本上一旦Containerviewcontroller加载,我就无法使用导航栏中的任何按钮。 TableViewController中的触控仍然已注册,它似乎只是UIBarButtonItems内的UINavigationBar

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

提前谢谢!!

编辑:如果我删除嵌入式故事板UINavigationController,我可以让按钮工作,但我需要它,以便当来自另一个UINavigationController的<Back时箭头没有显示在NavigationController的顶部。

1 个答案:

答案 0 :(得分:0)

解决方案是使用模态segue到视图控制器,因为containerviewcontrollernavigationcontroller竞争,需要声明它自己而不是简单地被推到导航堆栈上。