导航栏大标题 - 动画问题

10
我在导航栏上使用了大标题,在点击单元格进入下一个控制器时,大标题会出现奇怪的动画(如下面的gif所示)。它不会立即消失。
我尝试了以下解决方案,但没有用(https://www.morningswiftui.com/blog/fix-large-title-animation-on-ios13

enter image description here

我的代码:

在第一个视图控制器上:

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

        navigationItem.title = "New Order"
        navigationController?.navigationBar.prefersLargeTitles = true
}

在第二个视图控制器上(使用大标题):
override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        navigationItem.title = "Menu"
        self.navigationController?.navigationBar.prefersLargeTitles = false
}

编辑:

Fabio的答案是解决方案,但现在我有另一个问题:

当我点击单元格时,导航栏的一部分会变成黑色(如下所示)

enter image description here


你能给我展示一下代码吗? - hong developer
你尝试过添加 viewWillDisappear 函数和移除导航栏标题吗? - Andres Gomez
我添加了我的代码!我尝试了viewWillDisappear函数,但没有结果。 - Alex Giatrakis
@AlexGiatrakis,您能否详细解释一下您是如何解决导航标题问题的?我也遇到了同样的问题。 - Adeel Ur Rehman
5个回答

7

尝试在第一个视图控制器中插入:

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

    navigationItem.title = "New Order"
    navigationController?.navigationBar.prefersLargeTitles = true
    navigationItem.largeTitleDisplayMode =  .always
 }

在第二个视图控制器上:

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

    navigationItem.title = "Menu"
    navigationItem.largeTitleDisplayMode = .never
}

如果在第二个视图控制器中不将prefersLargeTitles设置为false,则此工作有效。 - Evgeniy

5

第二个问题解决方案如下: 在SceneDelegate中: var window: UIWindow? 在函数scene中添加以下代码:

window?.backgroundColor = .yourColor

像这样:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    guard let _ = (scene as? UIWindowScene) else { return }
    window?.backgroundColor = .white
}

设置你想要的颜色,就这么简单 :)


谢谢!它有效了!你能解释一下这行代码具体是做什么的吗? - Alex Giatrakis
1
只是应用程序的背景...您看到的黑色条是应用程序的背景,不是条形图 :) - Fabio
或者将extendedLayoutIncludesOpaqueBars设置为true,因为视图控制器的框架不是全屏。 - protuberian

3

在第二个视图控制器中,尝试使用viewDidLoad而不是viewWillAppear


这正是我实现的问题所在。 - MMujtabaRoohani
从Storyboard中,我需要在详细视图控制器中将largeTitleDisplayMode设置为.never并且在viewWillAppear中删除prefersLargeTitle - MMujtabaRoohani

2

将此扩展复制到设置导航栏:

extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
if #available(iOS 13.0, *) {
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
    navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
    navBarAppearance.backgroundColor = backgoundColor
    navigationController?.navigationBar.standardAppearance = navBarAppearance
    navigationController?.navigationBar.compactAppearance = navBarAppearance
    navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance

    navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
    navigationController?.navigationBar.isTranslucent = false
    navigationController?.navigationBar.tintColor = tintColor
    navigationItem.title = title

} else {
    // Fallback on earlier versions
    navigationController?.navigationBar.barTintColor = backgoundColor
    navigationController?.navigationBar.tintColor = tintColor
    navigationController?.navigationBar.isTranslucent = false
    navigationItem.title = title
}}}

如何使用,在viewWillAppear中调用

configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "YourTitle", preferredLargeTitle: true)

现在在didSelectRow中调用第二个控制器并使用pushViewController进行推送,如下所示:

let controller = YourViewController()
    navigationController?.pushViewController(controller, animated: true)

在第二个控制器的viewDidLoad方法中,将大标题设置为false,代码如下:
navigationItem.largeTitleDisplayMode = .never

如果您想要浅色内容,请在info.plist中将ViewController-based状态栏设置为NO。 如果您不想要大标题,请将其设置为false 在iOS 13上进行了测试,希望这可以帮助您 :) 现在没问题了 :)


谢谢你的回答。我尝试了你告诉我的一切,但问题仍然存在。 - Alex Giatrakis
1
@AlexGiatrakis 总结:在第一个控制器中复制扩展,在第一个控制器的viewWillAppear中配置navBar:configureNavigationBar(largeTitleColor:.yourColor,backgoundColor:.yourColor,tintColor:.yourColor,title:“YourTitle”,preferredLargeTitle:true),现在调用pushViewController来显示第二个控制器,在第二个控制器的viewDidLoad中复制此行:navigationItem.largeTitleDisplayMode = .never,就完成了...已测试。 - Fabio
谢谢你的回复。但是现在我又有了其他问题。我已经编辑了我的帖子。 - Alex Giatrakis
如果没有使用UINavigationBarAppearance,在使用大标题时,导航栏背景会出现显示错误。感谢@Fabio。 - spnkr
@spnkr 很高兴能够帮到你 :) - Fabio

1

所以你想让你的第一个视图控制器有大标题,那么将以下代码添加到你的第一个视图控制器中的viewWillAppear(animated:)方法中

self.navigationItem.largeTitleDisplayMode = .automatic
self.navigationController?.navigationBar.prefersLargeTitles = true

如果你想让下一个视图控制器没有大标题,那么请在下一个视图控制器的viewWillAppear(animated:)方法中添加以下代码:

self.navigationItem.largeTitleDisplayMode = .never

结论是,只有当您希望您的视图控制器在出现视图时显示大标题时,您才需要将self.navigationController?.navigationBar.prefersLargeTitles设置为true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接