我有一个自定义的 SwiftUI 标题 View ,它由几个 Text
和一个 Image
组成(为了简化,省略了 Image
) 。带有标题 View 的 SwiftUI View 是从 UIViewController
呈现的,因此我需要一个自定义后退按钮,用于从 View
导航回来(显示在 UIHostingController
) 到之前呈现它的 UIViewController
。
我希望这个自定义后退按钮看起来与系统后退按钮完全相同,但是,我找不到适合它的系统图像。我尝试过 Image(systemName: "chevron.left")
和 Text("❮")
(以及几乎所有其他系统图像和 unicode 箭头字符) ,但这些都没有提供系统后退按钮的外观。
有什么方法可以匹配 SwiftUI 中系统后退按钮的外观吗?
这就是系统后退按钮的样子(尾随按钮是 Unicode 左箭头,前导按钮是系统后退按钮):
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/