【问题标题】:Changing the back button of UINavigaitonBar with MVVM+C使用 MVVM+C 更改导航栏的后退按钮
【发布时间】:2021-12-01 04:41:53
【问题描述】:

我正在使用 MVVM+C 模式来构建我的应用程序。目前,我遇到了将导航栏的本机后退按钮标题和图像更改为没有标题的自定义图像的问题。我已经尝试了很多我能找到的解决方案,但没有设置不同的标题甚至图像。我在 AppDelegate.swift 中得到了这段代码:

let navigationController: UINavigationController = .init()
    
    if #available(iOS 13.0, *) {
        let appearence = UINavigationBarAppearance()
        appearence.configureWithOpaqueBackground()
        appearence.backgroundColor = .backgroundColor
        appearence.shadowColor = nil
        appearence.shadowImage = nil
        
        navigationController.navigationBar.standardAppearance = appearence
        navigationController.navigationBar.scrollEdgeAppearance = navigationController.navigationBar.standardAppearance
    } else {
        navigationController.navigationBar.isTranslucent = false
        navigationController.navigationBar.barTintColor = .backgroundColor
        navigationController.navigationBar.shadowImage = nil
        navigationController.navigationBar.shadowColor = nil
    }
    // This code is not working at all, always get "Back" as a default with default image =====

    let backButtonBackgroundImage = UIImage(named: "backButton")
    navigationController.navigationBar.backIndicatorImage = backButtonBackgroundImage
    navigationController.navigationBar.backIndicatorTransitionMaskImage = backButtonBackgroundImage
    
    let backBarButtton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    navigationController.navigationItem.backBarButtonItem = backBarButtton
    
    // =========

    navigationController.navigationBar.tintColor = .primary
    
    window?.rootViewController = navigationController
    window?.makeKeyAndVisible()

另外,我关注了official documentation,但没有成功。默认情况下,我已将导航栏设置为隐藏(因为多次不需要),我将其显示在 ViewWillAppear 并隐藏在 ViewWillDisappear 方法中。

有人知道发生了什么吗?谢谢!

这段代码的结果:

预期结果:

这是我使用新代码得到的结果:

解决方案: 使用 Scott 的代码后,我能够更改导航栏的图像和外观,但我失去了向后滑动的能力。将此代码添加到 UINavigationBar 扩展后,我能够将其取回:

extension UINavigationController: UIGestureRecognizerDelegate {
@objc func goBack(sender: Any?) {
    self.popViewController(animated: true)
}

override open func viewDidLoad() {
    super.viewDidLoad()
    interactivePopGestureRecognizer?.delegate = self
}

public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    return viewControllers.count > 1
}
}

【问题讨论】:

    标签: swift uinavigationcontroller uinavigationbar uinavigationitem uinavigationbarappearance


    【解决方案1】:

    下面是一些 Playground 代码,其中显示了带有自定义后退按钮的 UINavigationController

    请注意,它的作用是隐藏系统提供的后退按钮,然后替换另一个仍执行“后退”操作但在自定义 UINavigationController 上的按钮。

    可能有一种更有效的方法来复制不涉及自定义类和自定义目标操作设置的“返回”功能,但我无法快速找到一个,因此可以将解决方案保留为供读者练习。

    import UIKit
    import SwiftUI
    import PlaygroundSupport
    
    NSSetUncaughtExceptionHandler { error in
        debugPrint(error)
    }
    
    class MyNavController : UINavigationController {
        @objc func goBack(sender: Any?) {
            self.popViewController(animated: true)
        }
    }
    
    let navDestination1 = UIViewController()
    navDestination1.navigationItem.title = "Destination 1"
    
    let navigationController = MyNavController(rootViewController: navDestination1)
    
    if #available(iOS 13.0, *) {
        let appearence = UINavigationBarAppearance()
        appearence.configureWithOpaqueBackground()
        appearence.backgroundColor = .purple
        appearence.shadowColor = nil
        appearence.shadowImage = nil
    
        navigationController.navigationBar.standardAppearance = appearence
        navigationController.navigationBar.scrollEdgeAppearance = navigationController.navigationBar.standardAppearance
    } else {
        navigationController.navigationBar.isTranslucent = false
        navigationController.navigationBar.barTintColor =  .purple
        navigationController.navigationBar.shadowImage = nil
    }
    
    let navDestination2 = UITableViewController()
    navDestination2.navigationItem.title = "Destination 2"
    navDestination2.navigationItem.hidesBackButton = true
    navDestination2.navigationItem.leftBarButtonItem = UIBarButtonItem(
        image: UIImage(systemName: "multiply.circle.fill"),
        style: UIBarButtonItem.Style.done,
        target: navigationController,
        action: #selector(MyNavController.goBack))
    
    
    navigationController.pushViewController(navDestination2, animated: true)
    
    navigationController.view.bounds = CGRect(x: 0,y: 0,width: 320,height: 480)
    
    PlaygroundSupport.PlaygroundPage.current.liveView = navigationController
    

    【讨论】:

    • 嗨,斯科特,对我来说,在我的项目中,所有事情都保持不变。当我直接在 ViewController 或 AppDelegate 中使用您的代码时,没有更改图标或标题...我仍然只能更改色调。
    • 我发布的示例是否在操场上运行,是否在您的设置中显示自定义后退按钮?
    • 是的,我可以在操场上运行它,并且一切都按需要设置...但是当我将相同的代码放在项目中的同一个地方时,什么也没有发生。我只能改变颜色...
    • 检查项目的结果,它与游乐场不同
    • 意识到我没有您的图像,因此我的代码使用其中一个系统图像(其中带有 X 的圆形按钮)而不是您想要使用的任何图像。
    猜你喜欢
    • 2014-11-21
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 2014-04-30
    • 1970-01-01
    相关资源
    最近更新 更多