ios - 在 SwiftUI NavigationView 上显示系统后退按钮,没有之前的 NavigationLink

标签 ios swift swiftui

我有一个自定义的 SwiftUI 标题 View ,它由几个 Text 和一个 Image 组成(为了简化,省略了 Image) 。带有标题 View 的 SwiftUI View 是从 UIViewController 呈现的,因此我需要一个自定义后退按钮,用于从 View 导航回来(显示在 UIHostingController) 到之前呈现它的 UIViewController

我希望这个自定义后退按钮看起来与系统后退按钮完全相同,但是,我找不到适合它的系统图像。我尝试过 Image(systemName: "chevron.left")Text("❮") (以及几乎所有其他系统图像和 unicode 箭头字符) ,但这些都没有提供系统后退按钮的外观。

有什么方法可以匹配 SwiftUI 中系统后退按钮的外观吗?

这就是系统后退按钮的样子(尾随按钮是 Unicode 左箭头,前导按钮是系统后退按钮): system back button

还有我的自定义后退按钮(如您所见,它比系统按钮小得多): enter image description here

TitleView.swift:

class TitleViewModel: ObservableObject {
    let backAction: () -> ()
    @Published var name: String
    @Published var subtitle: String?

    init(name: String, subtitle: String?, backAction: @escaping () -> ()) {
        self.name = name
        self.subtitle = subtitle
        self.backAction = backAction
    }
}

struct TitleView: ViewModifier {
    @ObservedObject var viewModel: TitleViewModel

    func body(content: Content) -> some View {
        ZStack(alignment: .top) {
            NavigationView {
                VStack {
                    content
                        .navigationBarTitle("", displayMode: .inline)
                        .navigationBarItems(leading: backButton)
                    NavigationLink(destination: Text("Destination").navigationBarItems(trailing: Text("❮")), label: { Text("Next")
                    })
                }
            }
            titleView
        }
    }

    private var backButton: some View {
        Button(action: viewModel.backAction) { Image(systemName: "chevron.left") }
    }

    private var titleView: some View {
        VStack {
            Text(viewModel.name)
            Text(viewModel.subtitle ?? "")
        }
    }
}

extension View {
    func titleView(_ viewModel: TitleViewModel) -> some View {
        modifier(TitleView(viewModel: viewModel))
    }
}

详细信息 View .swift

public struct DetailsView: View {
    public var backAction: () -> ()

    public var body: some View {
        Text("Text")
            .titleView(TitleViewModel(name: "Title", subtitle: "SubTitle", backAction: backAction))
    }
}

public class DetailsViewController: UIHostingController<DetailsView> {
    public override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(true, animated: false)
    }
}

public struct RootView: View {
    public var next: () -> ()

    public var body: some View {
        VStack {
            Text("Root")
            Button(action: next, label: { Text("Next") })
        }
    }
}

并在 SceneDelegate 中,设置一个 UINavigationController,它将 UIHostingController 呈现为 rootViewController

func instantiateRootViewController() -> UIViewController {
    let navigationController = UINavigationController()
    let detailsView = DetailsView(backAction: { navigationController.popViewController(animated: true) })
    let presentDetailsView = { navigationController.pushViewController(DetailsViewController(rootView: detailsView), animated: true) }
    let rootViewController = UIHostingController(rootView: RootView(next: presentDetailsView))
    navigationController.pushViewController(rootViewController, animated: true)
    return navigationController
}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        let rootViewController = instantiateRootViewController()
        window.rootViewController = rootViewController
        self.window = window
        window.makeKeyAndVisible()
    }
}

最佳答案

您可以尝试以下方法:

private var backButton: some View {
    Button(action: {}) {
        Image(systemName: "chevron.left")
            .scaleEffect(0.83)
            .font(Font.title.weight(.medium))
    }
}

您也可以选择应用.offset,但这可能无法正确适应更大的辅助字体大小:

.offset(x: -7, y: 0)

关于ios - 在 SwiftUI NavigationView 上显示系统后退按钮,没有之前的 NavigationLink,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63720679/

相关文章:

ios - 使用导航 Controller 作为 View 更改 Popovercontroller 中导航栏和工具栏的色调

ios - Swift 初始化方法错误 : Declaration 'init(coder:)' cannot override more than one superclass declaration

swift - 编译失败 : argument type 'Character' does not conform to expected type 'ExpressibleByStringLiteral'

android - 如何在点击文本时更改文本的颜色和/或装饰

java - InetAddress.getAllByName() 抛出 UnknownHostException

swift - 为什么 Swift 隐式解包可选 `nil` ?

ios - Swift 2.2 - 除非我关闭优化,否则代码会崩溃(-在线)

swift - 如何在 SwiftUI 中子类化 @State 属性包装器

SwiftUI Nested NavigationView navigationBar消失

objective-c - Objective-C/iOS 编程中有用的指针算法的任何示例?