Как добавить распознаватель жестов в NavigationController.view и сохранить его поведение только для первого V C из иерархии N C? - PullRequest
0 голосов
/ 09 июля 2020

У меня есть реализация бокового меню, где ContainerViewController содержит sideMenuV C и FeedV C, встроенный в N C (свойство centerNavigationController в реализации ContainerV C). FeedV C показывает список статей в tableView.

Я добавляю panGestureRecognizer в centerNavigationController. Анимация отлично работает с FeedV C, за исключением того, что она остается неизменной для следующих V C в иерархии. ArticleV C (отображается после выбора статьи в FeedV C) не имеет смахивания назад к go (поведение по умолчанию N C) и смахивания влево, чтобы представить SFSafariViewController, который я добавил сам внутри ArticleV C class, он читает panGesture, который я добавил в centerNavigationController, и перетаскивает sideMenu с помощью правого свайпа. И я хочу, чтобы ArticleV C сохранил поведение по умолчанию смахивания вправо и смахивание влево, чтобы представить SafariV C, без представления sideMenu.

Я попытался добавить panGesture только в FeedV C внутри класса ContainerViewController, то есть добавление его в подкласс UIViewController, а не UINavigationController. Но он не анимирует панель навигации (она не перемещается).

И если я первым добавляю ContainerV C в иерархию N C, анимация там тоже некорректна, navBar не перемещается, и это кажется не совсем правильным подходом, потому что он похож на контейнер и его не должно быть в этой иерархии навигации (я могу ошибаться). с этим? Заранее спасибо

ContainerV C код


class ContainerController: UIViewController {
    
    // MARK:- Properties
    private var sideMenuController: SideMenuController!
    private var centerNavigationController: UINavigationController!
    private var isExpanded: Bool = false
    
    // MARK:- View Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        configureFeedViewController()
        configureSideMenuController()
    }
    
    // MARK:- Methods
    private func configureFeedViewController() {
        let feedViewController = FeedViewController()
        feedViewController.delegate = self
        centerNavigationController = UINavigationController(rootViewController: feedViewController)
        
        view.addSubview(centerNavigationController.view)
        addChild(centerNavigationController)
        centerNavigationController.didMove(toParent: self)
        addPanGestureToCenterNC()
    }
    
    private func configureSideMenuController() {
        if sideMenuController == nil {
            sideMenuController = SideMenuController()
            sideMenuController.delegate = self
            view.insertSubview(sideMenuController.view, at: 0)
            addChild(sideMenuController)
            sideMenuController.didMove(toParent: self)
        }
    }
    
    private func animatePanel(shouldExpand: Bool, sideMenuOption: SideMenuOption?)  {
        if shouldExpand {
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
                self.centerNavigationController.view.frame.origin.x = self.centerNavigationController.view.frame.width - (self.centerNavigationController.view.frame.width / 5)
            }, completion: nil)
        } else {
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
                self.centerNavigationController.view.frame.origin.x = 0
            }) { (_) in
                guard let sideMenuOption = sideMenuOption else { return }
                self.didSelectSideMenuOption(sideMenuOption: sideMenuOption)
            }
        }
    }
    
    func didSelectSideMenuOption(sideMenuOption: SideMenuOption?) {
        //
    }
    
    private func addPanGestureToCenterNC() {
        let panGestureRecognizer = UIPanGestureRecognizer(
            target: self,
            action: #selector(handlePanGesture(_:)))
        centerNavigationController.view.addGestureRecognizer(panGestureRecognizer)
    }
    
}

// MARK:- FeedViewControllerDelegate
extension ContainerController: FeedViewControllerDelegate {
    func handleSideMenuToggle(forSideMenuOption sideMenuOption: SideMenuOption?) {
        if !isExpanded {
            configureSideMenuController()
        }
        isExpanded = !isExpanded
        animatePanel(shouldExpand: isExpanded, sideMenuOption: sideMenuOption)
    }
}

// MARK:- UIGestureRecognizerDelegate
extension ContainerController: UIGestureRecognizerDelegate {
    
    @objc func handlePanGesture(_ recognizer: UIPanGestureRecognizer) {
        let gestureIsDraggingFromLeftToRight = (recognizer.velocity(in: view).x > 0)
        
        switch recognizer.state {
        case .began:
            if gestureIsDraggingFromLeftToRight {
                configureSideMenuController()
            }
        case .changed:
            if let rview = recognizer.view,
                (rview.center.x + recognizer.translation(in: view).x > view.bounds.size.width / 2) {
                rview.center.x = rview.center.x + recognizer.translation(in: view).x
                recognizer.setTranslation(CGPoint.zero, in: view)
            }
        case .ended:
            isExpanded = gestureIsDraggingFromLeftToRight ? true : false
            animatePanel(shouldExpand: isExpanded, sideMenuOption: nil)
        default:
            break
        }
    }
    
}

...