如何在 SwiftUI 视图中包装 UIBarButtonItem?

Posted

技术标签:

【中文标题】如何在 SwiftUI 视图中包装 UIBarButtonItem?【英文标题】:How to wrap a UIBarButtonItem in a SwiftUI View? 【发布时间】:2020-05-21 15:38:39 【问题描述】:

我正在尝试为NavigationBar 制作一个自定义后退按钮,我可以在其中放置我喜欢的任何文本。我的主要用例是我的一些视图没有标题,当我从中单击新视图时,导航栏中新视图的后退按钮没有文本,只有一个箭头。它使用户很难点击它。我希望设置一个自定义后退按钮,其中包含文本“Back”,但也有后退按钮图标,并且与 SwiftUI 的动画机制完美配合。

这是我目前尝试将 UIKit 元素包装在 View 中,以便我可以将其与 SwiftUI 一起使用:

struct CustomBackButton: UIViewControllerRepresentable 
    typealias UIViewControllerType = ViewController


    @Binding var title: String

    func makeUIView(context: Context) -> UIBarButtonItem 
        return UIBarButtonItem()
    

    func updateUIView(_ uiView: UIBarButtonItem, context: Context) 
        uiView.title = title
    

这显然不起作用,我目前不确定如何使其真正起作用。

我的理想方案是 CustomBackButton 可以工作,这样我就可以在 SwiftUI 中像这样使用它:

    var body: some View 
        NavigationView 
            Text("Page with no title")
                .navigationBarItems(leading: CustomBackButton(title: "Back"))
                .navigationBarTitle("", displayMode: .large)
        
    

我必须做些什么才能将CustomBackButton 正确包装到 SwiftUI View 中?

【问题讨论】:

UIBarButtonItem 既不是 UIView 也不是 UIViewController,所以你不能将它包装成可表示的。您能详细说明这里将要实现的目标吗?为什么你不想像我们所有人一样对 .navigationBarItems 使用原生 SwftUI 视图? @Asperi 我尝试使用自定义的前导 navigationBarItem,但它不能很好地与 SwiftUI 的内置动画配合使用。我让自定义按钮看起来像是原生按钮,但它的行为和动画都不像一个 【参考方案1】:

如果您只是想拥有自定义文本,那么无需为 UIKit 操心。以下是在 SwiftUI 中制作自定义后退按钮的方法:

struct ViewWithCustomBackButton: View 
    @Environment(\.presentationMode) var presentationMode

    var body: some View 
        HStack 
            ...
        
        .navigationBarTitle(Text("Your View"), displayMode: .inline)
        // Hide the system back button
        .navigationBarBackButtonHidden(true)
        // Add your custom back button here
        .navigationBarItems(leading:
            Button(action: 
                self.presentationMode.wrappedValue.dismiss()
            ) 
                HStack 
                    Image(systemName: "arrow.left.circle")
                    Text("Go Back")
                
        )
    

您也可以在此处查看答案以获取更多信息:Custom back button for NavigationView's navigation bar in SwiftUI

【讨论】:

不幸的是,我已经尝试过这种方法,但它不能很好地与 SwiftUI 的内置动画配合使用。前一个视图的标题只是向左平移,并且前导自定义后退按钮只是突然弹出,而不是如果没有使用自定义前导按钮,它会自然动画化

以上是关于如何在 SwiftUI 视图中包装 UIBarButtonItem?的主要内容,如果未能解决你的问题,请参考以下文章

如何实现一个自定义属性包装器,它将发布 SwiftUI 的更改以重新呈现它的视图

在 SwiftUI 中使用 @State 属性包装器未更新视图

如何在 SwiftUI 中更改滚动视图的滚动方向?

如何让 SwiftUI Picker 在子视图中工作? (变灰)

如何防止 SwiftUI 像使用 @StateObject 一样重新初始化我的包装属性?

如何在 SwiftUI 中制作水平列表?