列表内的SwiftUI程序化导航

时间:2020-06-07 17:37:12

标签: ios swift swiftui

我对导航的要求如下所示:

Navigation 每个详细信息屏幕都可以导航到下一个和上一个详细信息屏幕。同时,“后退”按钮应始终返回主列表(而不是先前的详细信息屏幕)。

我正在为如何在SwiftUI中实现这一目标而苦苦挣扎?

这是我到目前为止所拥有的:

struct ListView: View {
    @State private var currentDetailShown: Int?
    @State private var listItems: [Int] = Array(repeating: 0, count: 10)

    func goToNext() {
        if let idx = self.currentDetailShown {
            self.currentDetailShown = min(self.listItems.count - 1, idx + 1)
        }
    }

    func goToPrev() {
        if let idx = self.currentDetailShown {
            self.currentDetailShown = max(0, idx - 1)
        }
    }

    var body: some View {
        List {
            ForEach(0..<listItems.count) { index in
                NavigationLink(destination: DetailView(goToNext: self.goToNext, goToPrev: self.goToPrev),
                               tag: index,
                               selection: self.$currentDetailShown) {
                    ListItem(score: listItems[index])
                }
                .isDetailLink(false)
                .onTapGesture {
                    self.currentDetailShown = index
                }
            }
        }
    }
}

此代码的作用是,从第一个详细信息视图将其移至下一个详细信息视图,然后立即跳回到列表视图。

我觉得我想得太过分了,或者缺少明显的东西...

1 个答案:

答案 0 :(得分:1)

您可以导航到detailView,而不是从列表中导航到每个详细信息,该视图可以通过在可观察对象中使用已发布的变量来单独显示每个详细信息。这是一个例子

struct MainView: View{
    @EnvironmentObject var viewModel: ViewModel

    var body: some View{
        NavigationView{
            VStack{
            ForEach(self.viewModel.details, id:\.self){ detail in
                NavigationLink(destination: DetailView(detail: self.viewModel.details.firstIndex(of: detail)!).environmentObject(ViewModel())){
            Text(detail)
            }
        }
        }
    }
    }
}

class ViewModel: ObservableObject{
    @Published var showingView = 0
    @Published var details = ["detail1", "detail2", "detail3", "detail4", "detail5", "detail6"]
}

struct DetailView: View{
    @EnvironmentObject var viewModel: ViewModel
    @State var detail: Int
    var body: some View{
        VStack{
        IndivisualDetailView(title: viewModel.details[detail])

        Button(action: {
            self.viewModel.showingView -= 1
        }, label: {
            Image(systemName: "chevron.left")
        })
            Button(action: {
                self.viewModel.showingView += 1
                print(self.viewModel.showingView)
            }, label: {
                Image(systemName: "chevron.right")
            })
    }
    }
}
struct IndivisualDetailView: View{
    @State var title: String
    var body: some View{
        Text(title)
    }
}