Изменение цвета навигационной панели во время вызова контроллера просмотра

У меня есть три контроллера вида. В первом представлении контроллера (FirstVC) цвет оттенка панели навигации является clearColor, а сам план является полупрозрачным. Когда я нажимаю на что-то, я нажимаю на SecondVC, где панель навигации должна быть непрозрачной. Поэтому я устанавливаю barTintColor на некоторое значение цвета и устанавливаю isTranslucent в false. Когда я нажимаю на ThirdVC из SecondVC, навигационная панель снова должна быть полупрозрачной. Проблема возникает, когда я выхожу на ThirdVC и возвращаюсь к SecondVC. Панель навигации отображается как прозрачная на секунду, а затем становится непрозрачной по мере необходимости. Я не могу понять причину задержки.

Следующий метод вызывается из viewWillAppear() SecondVC. Я пробовал делать то же самое с viewWillDisappear() ThirdVC, но не имел никакого эффекта.

fileprivate func configureNavigationBar(){

        self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
        self.navigationController?.navigationBar.shadowImage = nil
        self.navigationController?.navigationBar.isTranslucent = false
        self.navigationController?.navigationBar.barTintColor = Style.Movie.primaryBackgroundColor
        let titleDict: NSDictionary = [NSForegroundColorAttributeName: UIColor.white]
        self.navigationController?.navigationBar.titleTextAttributes = titleDict as? [String:Any]
    }

Он отлично работает, если я откидываюсь назад, а не нажимаю кнопку "Назад".

Ответ 1

используйте эту функцию в thiredVC

override func willMove(toParentViewController parent: UIViewController?) {
          self.navigationController?.navigationBar.barTintColor = color use in secondVC
    }

Ответ 2

Наткнулся на эту ветку и придумал хорошее решение, чтобы помочь всем в будущем.

Сначала создайте пользовательский UINavigationController с типом enum, который поможет определить ваши настройки навигации:

enum NavType: Int {
    case light, medium, dark
}

class NavigationController: UINavigationController {

    /* 
      Fetch the last controller in the navigation stack so the 
      ViewControllers can switch the navType
    */
    var previousController: ViewController? {
        if viewControllers.count > 1 {
            return viewControllers[viewControllers.count-2] as? ViewController
        }
        return nil
    }

    var navType: NavType = .light {
        didSet { updateNavType() }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationBar.isTranslucent = false
        layoutNavigationTheme()
    }

    func layoutNavigationTheme() {
        switch navType {
        case .dark:
            view.backgroundColor = .white
            navigationBar.backgroundColor = .black
            navigationBar.barTintColor = .black
            navigationBar.tintColor = .white

        ... // Set up as per enum
        }
    }

}

Затем создайте пользовательский UIViewController используя willMove(...:

class ViewController: UIViewController {

    var navType: NavType = .light

    var navigation: NavigationController? {
        return navigationController as? NavigationController
    }

    // Override willMove will fetch the last controller and set the navType
    override func willMove(toParentViewController parent: UIViewController?) {
        super.willMove(toParentViewController: parent)

        if let navigation = navigation {
            navigation.navType = navigation.previousController?.navType ?? .light
        }
    }

}

Затем просто в ваших UIViewControllers подкласс вашего нового ViewController и установите navType в viewDidLoad:

class MainController: ViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        navType = .dark
    }

}

Ответ 3

Вы можете создать настраиваемую панель навигации для SecondVC. И вызовите метод -popViewController вручную, нажав кнопку "Назад".

Ответ 4

Другое решение, которое работает, это переопределение pushViewController (_ viewController: UIViewController, animated: Bool) и popViewController (animated: Bool) → UIViewController? UINavigationController.

class CustomNC : UINavigationController {
    public override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }

    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nil, bundle: nil)
    }

    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private var isCustomDesign: Bool { 
        return viewControllers.count == 1 && viewControllers[0] is MyCustomVC // Or any other condition 
    }

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        super.pushViewController(viewController, animated: animated)
        if isCustomDesign {
            navigationBar.barTintColor = UIColor.red
        } else {
            navigationBar.barTintColor = UIColor.green
        }
    }

    override func popViewController(animated: Bool) -> UIViewController? {
        let viewController = super.popViewController(animated: animated)
        if isCustomDesign {
            navigationBar.barTintColor = UIColor.red
        } else {
            navigationBar.barTintColor = UIColor.green
        }
        return viewController
    }
}