使用SwitUI执行操作后如何转到特定的选项卡视图?

时间:2019-11-10 20:25:12

标签: swiftui

我想构建一个应用程序来管理虚拟数据中心(服务器,防火墙策略,负载平衡器...)。我有两个部分(使用标签视图)。其中一个列出了您在数据中心中创建的所有元素的列表。另一部分是创建新元素。如果启动该应用程序,则从列表部分开始。然后,我尝试创建一个新服务器。为此,我转到“创建”部分,单击“服务器”并选择一个“大小”,这是我无法解决的前两个问题:

  1. 为什么选择器的选项会在屏幕顶部进行小跳转?如何删除它?
  2. 屏幕顶部和选择器的选项之间空间太大。如何将其删除?

最后一个问题是创建服务器后,我返回到“创建”部分,我想直接进入“列表”部分。我该怎么办?

这里是基本代码,可查看我所遇到的问题。预先感谢您的帮助!

import SwiftUI

struct ContentView: View {
    @State private var selectedTab = 1
    var body: some View {
        TabView(selection: $selectedTab){
            CreateView()
                .tabItem {
                    Image(systemName: "plus")
                    Text("Create")
                }.tag(0)
            ListView()
                .tabItem {
                    Image(systemName: "cloud")
                    Text("List")
                }.tag(1)
        }
    }
}


struct CreateView: View {
    var body: some View {
         VStack{
           NavigationView{
               List{
                   NavigationLink(destination: CreateServerView()){
                       Text("Server")
                   }
                   Text("Firewall Policy")
                   Text("Load Balancer")
               }
               .navigationBarTitle("Select the element you want to create", displayMode: .inline)
           }
        }
    }
}

struct ListView: View {
    var body: some View {
        NavigationView{
            List{
                Section(header: Text("Servers")){
                    Text("Server 1")
                    Text("Server 2")
                }
                Section(header: Text("Firewall policies")){
                    Text("Firewall 1")
                    Text("Firewall 2")
                }
            }
            .navigationBarTitle("My virtual datacenter", displayMode: .large)
        }
    }
}

struct CreateServerView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @State private var name: String = ""
    @State private var selectedFixServer = 0

    @State private var serverType = ["S", "M", "L", "XL"]
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Name of the server")){
                    TextField("Name", text: $name)
                }
                Picker(selection: $selectedFixServer, label: Text("Size")) {
                    ForEach(0 ..< serverType.count) {
                        Text(self.serverType[$0])
                    }
                }
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
        }
        .navigationBarTitle("Create Server")
        .navigationBarBackButtonHidden(true)
        .navigationBarItems(
            leading:
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Cancel")
                },
            trailing:
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Create")
                }
        )
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

2 个答案:

答案 0 :(得分:2)

一个变种是使用.pickerStyle(SegmentedPickerStyle()),但我不知道这是否适合您。有了这个决定,两个问题就解决了,您不需要太多空间:

enter image description here

关于:

  

直接转到“列表”部分

在您的示例中,我只是在 CreateServerView 中将@Binding var selectedTab设为并在将其关闭之前将其更改:

struct CreateServerView: View {
    // ...
    @Binding var selectedTab: Int
    // ...
        trailing:
                Button(action: {
                    self.selectedTab = 1
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Create")
                })
// ...
}

您需要传递此变量,创建服务器后它将直接进入列表

答案 1 :(得分:1)

  
      
  1. 为什么选择器的选项会跳到屏幕顶部?如何删除它?
  2.   
  3. 屏幕顶部和选择器的选项之间的空间太大。如何将其删除?
  4.   

这是因为您在现有NavigationView中创建了第二个NavigationView。因此,要解决此问题,只需在CreateServerView中删除NavigationView(例如,将其替换为VStack等)

注意:当我尝试使用您的代码时,我还注释了下两行

//                .navigationBarTitle("")
//                .navigationBarHidden(true)