我有一个自定义的SwiftUI标题视图,该视图由多个Text
和一个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()
}
}
答案 0 :(得分:0)
您可以尝试以下操作:
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)