You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:从子ViewController返回根VC时平滑缩小Large UINavigationBar

Smooth Large Navigation Bar Transition When Returning to Root VC

Hey there! Let's fix that seamless transition you're aiming for—getting the large navigation bar in your child view controller to smoothly shrink back to the default size when returning to the root VC, just like the App Store does. I see you don't want to fully remove the large bar capability from the parent, so we'll adjust how you're handling the large title settings to leverage iOS's built-in animation.

The Issue with Your Current Setup

Right now, your disableLargeNavigationTitle function turns off the navigation bar's global prefersLargeTitles flag directly. This causes an abrupt jump instead of a smooth transition, because you're overriding the navigation controller's default behavior for animating between different title modes.

The Fix: Use Per-VC Title Display Modes

iOS 11+ handles smooth large title transitions automatically if you let it—instead of toggling the global prefersLargeTitles setting, you control each view controller's navigationItem.largeTitleDisplayMode. Here's how to adjust your code:

1. Update the enableLargeNavigationTitle Function

Keep the global prefersLargeTitles enabled on the navigation bar, and set the child VC's display mode to force large titles:

func enableLargeNavigationTitle(title: String) {
    self.navigationController?.view.backgroundColor = VVUtility.splashBackGroundColor()
    self.navigationItem.title = "\(title)".localized()
    self.navigationController?.navigationBar.titleTextAttributes = [
        NSAttributedString.Key.foregroundColor : UIColor.white,
        NSAttributedString.Key.font : VVUtility.normalFontWithPlusSize(increaseSize: -2.0)
    ]
    
    if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.isTranslucent = false
        // Keep global large title support enabled
        self.navigationController?.navigationBar.prefersLargeTitles = true
        self.navigationController?.navigationBar.backgroundColor = VVUtility.splashBackGroundColor()
        self.navigationController?.navigationBar.largeTitleTextAttributes = [
            NSAttributedString.Key.foregroundColor : UIColor.white,
            NSAttributedString.Key.font : VVUtility.normalFontWithPlusSize(increaseSize: 0.0)
        ]
        // Force this VC to show large titles
        self.navigationItem.largeTitleDisplayMode = .always
    } else {
        // Fallback on earlier versions
    }
}

2. Rewrite the disableLargeNavigationTitle Function

Instead of disabling global large titles, just tell the parent VC to never show them:

func disableLargeNavigationTitle() {
    if #available(iOS 11.0, *) {
        // Only disable large titles for THIS view controller
        self.navigationItem.largeTitleDisplayMode = .never
    } else {
        // Fallback on earlier versions
    }
}

3. Clean Up Your View Controller Code

  • Child View Controller: Remove any unnecessary overrides that might interfere with transitions. Keep it simple:
override func viewDidLoad() {
    super.viewDidLoad()
    self.initUI()
    super.enableLargeNavigationTitle(title: (self.favorty?.sellerProduct?.product?.name)!)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    super.removeTitleImage()
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
}
  • Parent View Controller: Avoid redundant calls to disableLargeNavigationTitle—one call in viewDidLoad is enough. The navigation controller will handle the animation automatically when you return:
override func viewDidLoad() {
    super.viewDidLoad()
    self.initUI()
    self.getData()
    super.disableLargeNavigationTitle()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.addSubview(searchBarBoxView)
    self.timerDelegate?.startTimer()
    self.navigationController?.setNavigationBarHidden(false, animated: true)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.searchBarBoxView.removeFromSuperview()
    self.timerDelegate?.stopTimer()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.tabBarController?.delegate = self
}

Why This Works

By keeping the navigation controller's prefersLargeTitles set to true globally, you let iOS manage the transition animation between the child VC's .always large title mode and the parent VC's .never mode. This gives you that smooth, gradient shrink effect just like the App Store uses—no extra animation code needed!

内容的提问来源于stack exchange,提问作者Omid Kia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:04:33