在 SwiftUI 中呈现和消除警报后工具栏“完成”按钮消失

问题描述 投票:0回答:1

问题是我添加了一个工具栏“完成”按钮,但是当我在同一视图上显示警报然后重新聚焦于文本字段时,工具栏“完成”按钮会在 SwiftUI 中自动消失。在

TitleWithTextfield
中,有一个文本字段和一个标签。我已经实施了验证;例如,如果文本字段为空并且用户点击提交按钮,则会显示一条警报,提示用户输入姓名或电子邮件。但是,当用户按下“确定”按钮并再次点击文本字段后,工具栏的“完成”按钮会自动消失。

这是代码:

var body: some View {
    NavigationView {
        ZStack {
            AppColors.primaryColor
                .ignoresSafeArea(.all)
            
                VStack {
                    
                    NavigationViewWithTitleInCenter(title: "Feedback", backButtonAction: {
                        // Call your function here
                        presentationMode.wrappedValue.dismiss()
                        print("Back button tapped!")
                    })
                    
                    Spacer()
                    
                    VStack {
                        
                        TitleWithTextfield(placeholder: "Enter Name", text: $name)
                        
                        TitleWithTextfield(placeholder: "Enter Email", text: $email)
                        
                        TitleWithTextfield(placeholder: "Enter Subject", text: $subject)
                        
                        TitleWithTextView(placeholder: "Enter Message", text: $description)
                        
                        PrimaryButton(title: "Submit").onTapGesture {
                            self.didTapSubmit()
                        }
                        
                    }
                    .toolbar {
                        
                        ToolbarItemGroup(placement: .keyboard) {
                            Spacer()
                            Button("Done") {
                                UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                            }
                            .foregroundColor(.blue)
                        }
                    }
                                   

                    Spacer()
                }
           

                .blur(radius: isLoading ? 1 : 0) // Apply blur when isLoading is true
                .loadingOverlay(isLoading: isLoading)


        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text("Message"), message: Text("\(alertMessage)"), dismissButton: .default(Text("OK")))
        }

    }
}
ios swift swiftui toolbar
1个回答
0
投票

我找到了一种更适合 SwiftUI 的方法来解决 SwiftUI 和 iOS 中工具栏(导航栏)消失的问题。 我使用工具栏来执行非常重要的命令 - 替代 macOS 中的应用程序菜单。因此,缺少工具栏会导致我的 iOS 应用程序瘫痪。它永远不应该(!)发生。然而,多种情况使其消失(例如当我关闭弹出视图或在主视图中滚动时)。为此,我似乎找到了一个切实可行的解决办法。 首先是生成工具栏的模板代码 - 这是用于在我的应用程序中生成基本内容视图的符号代码。

struct ContentView: View {
   
   var body: some View {
      
      // The NavigationStack ensures the presence of the navigationBar (toolBar)
      let theView =
      NavigationStack(root: {self.generateContentView()})
      
      return theView
   }
   
   func generateContentView() -> some View {
      let theView =
         Text("This is my content view")
       .toolbar {self.generateToolBar()}
   }

   @ToolbarContentBuilder
   func generateToolBar() -> some ToolbarContent {
      ToolbarItem(placement: .navigationBarTrailing) {
         Text("This is a toolbar item")
      }
   }
}

我的解决方案是,如果我无法阻止系统做出不显示工具栏的决定,我可以尝试通过将状态变量 navigationBarIsHidden 设置为 false 来撤消隐藏。

这里更新的代码在收到通知“renewToolbar”时将状态变量 naviationBarIsHidden 设置为 false。请注意 ContentView 的修饰符

.navigationBarHidden(self.navigationBarIsHidden)
以及通过
Task()
将 navigationBarIsHidden 延迟更改为 false。

struct ContentView: View {
   
   let document:ApplicationDocument
   
   @State var navigationBarIsHidden : Bool = false
   
   var body: some View {
      
      // The NavigationStack ensures the presence of the navigationBar (toolBar)
      let theView =
      NavigationStack(root: {self.generateContentView()})
         .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name(rawValue: "renewToolbar"), object: self.document), perform: { notification in
            self.navigationBarIsHidden = true
            Task() {
               self.navigationBarIsHidden = false 
            }})
      
      return theView
   }
   
   func generateContentView() -> some View {
      let theView =
         Text("This is my content view")
       .toolbar {self.generateToolBar()}
       .navigationBarHidden(self.navigationBarIsHidden)
   }

   @ToolbarContentBuilder
   func generateToolBar() -> some ToolbarContent {
      ToolbarItem(placement: .navigationBarTrailing) {
         Text("This is a toolbar item")
      }
   }
}

问题仍然存在:如果各种各样的事件都会导致导航栏消失,我应该什么时候发送此通知?解决方案是将其绑定到工具栏项本身之一的 .onDisappear 修饰符。

这是完整的代码:

struct ContentView: View {
   
   let document:ApplicationDocument
   
   @State var navigationBarIsHidden : Bool = false
   
   var body: some View {
      
      // The NavigationStack ensures the presence of the navigationBar (toolBar)
      let theView =
      NavigationStack(root: {self.generateContentView()})
         .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name(rawValue: "renewToolbar"), object: self.document), perform: { notification in
            self.navigationBarIsHidden.toggle()
            Task() {
               self.navigationBarIsHidden.toggle()
            }})
      
      return theView
   }
   
   func generateContentView() -> some View {
      let theView =
         Text("This is my content view")
       .toolbar {self.generateToolBar()}
       .navigationBarHidden(self.navigationBarIsHidden)
   }

   @ToolbarContentBuilder
   func generateToolBar() -> some ToolbarContent {
      ToolbarItem(placement: .navigationBarTrailing) {
         Text("This is a toolbar item")
            .onDisappear(perform: {
               NotificationCenter.default.post(name: NSNotification.Name(rawValue: "renewToolbar"), object: self.document)
            })
      }
   }
}

在我的实际应用程序中,我的通知实际上绑定到 TextField(搜索字段)而不是文本,以防万一这不是针对文本调用的。

结果是,当我关闭弹出视图时,工具栏仍然消失,但此后它立即重新出现。

我尝试了按照上面的建议更新视图 id 的解决方案。它对我不起作用。在 SwiftUI 中,替换 id 是一项繁重的操作,因为如果强制重新渲染整个视图层次结构。整个视图(在我的例子中:整个屏幕)都会重建。

© www.soinside.com 2019 - 2024. All rights reserved.