在没有以前 NavigationLink 的 SwiftUI NavigationView 上显示系统后退按钮
Posted
技术标签:
【中文标题】在没有以前 NavigationLink 的 SwiftUI NavigationView 上显示系统后退按钮【英文标题】:Display system back button on SwiftUI NavigationView with no previous NavigationLink 【发布时间】:2020-09-03 09:27:44 【问题描述】:我有一个自定义的 SwiftUI 标题视图,它由几个 Text
s 和一个 Image
组成(为了简化,省略了 Image
)。带有标题视图的 SwiftUI 视图是从 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))
DetailsView.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()
【问题讨论】:
【参考方案1】:您可以尝试以下方法:
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)
【讨论】:
谢谢,这仍然有点偏离系统设计,但我会尝试使用.font
尝试更紧密地匹配它。我没有意识到您也可以将Font
修饰符应用于Image
,很高兴知道。
@DávidPásztor 不客气,如果您找到更接近的匹配项,请告诉我。
将 Weight
更改为 .medium
就我所知,它仍然不是 100%,但我想说非常接近,以至于用户不会注意到差异,除非他们正在同时查看系统后退按钮和自定义后退按钮:)以上是关于在没有以前 NavigationLink 的 SwiftUI NavigationView 上显示系统后退按钮的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法向 NavigationLink 添加额外的功能? SwiftUI
创建没有后退按钮 SwiftUI 的 NavigationLink
如何在 SwiftUI 列表中设置 NavigationLink
如何在不更改 UI 的情况下添加 NavigationLink?