简体   繁体   English

SwiftUI:单击按钮时如何显示视图?

[英]SwiftUI: How to present view when clicking on a button?

I'm trying to make an app using Apple's SwiftUI and I need to have two buttons that present two different views in a single List row.我正在尝试使用 Apple 的SwiftUI制作一个应用程序,并且我需要有两个按钮在单个List行中显示两个不同的视图。

I use Xcode beta 7 and MacOS Catalina beta 7 .我使用Xcode beta 7MacOS Catalina beta 7 I've tried to add a Button that present the view but, I couldn't click it and when I tried on a simple Button outside the List and clicked it, the AddList() view didn't appear.我试图添加一个显示视图的Button ,但是我无法单击它,当我尝试使用List外的一个简单Button并单击它时, AddList()视图没有出现。 I've also tried adding a navigationButton inside navigationButton but it didn't work too.我也试着加入navigationButtonnavigationButton ,但它没有工作过。 Adding a tapAction doesn't work too when you click on it, the view still does not appear当您单击它时,添加一个tapAction也不起作用,该视图仍然没有出现

NavigationView {
            List(0..<5) { item in
                NavigationLink(destination: ContentOfList()) {
                    Text("hello") // dummy text
                    Spacer()
                    Text("edit")
                        .tapAction {
                            AddList() // This is the view I want to present
                    }
                }
                }.navigationBarItems(trailing: NavigationLink(destination: AddList(), label: { // doesn't work within navigationBarItems
                    Image(systemName: "plus.circle.fill")
                }))
        }

I expect the AddList() view to appear but in the two cases, it doesn't.我希望AddList()视图出现,但在这两种情况下,它没有。

Update: The NavigationButton was very short lived.更新: NavigationButton 的寿命很短。 In beta3 it is already deprecated.在 beta3 中它已经被弃用了。 I am updating the code to use its replacement: NavigationLink .我正在更新代码以使用其替代品: NavigationLink

You can present a view from all three places.您可以从所有三个位置呈现视图。 Here's how:就是这样:

在此处输入图片说明

import SwiftUI

struct ContentView: View {

    var body: some View {
        NavigationView {
            TopView().navigationBarTitle(Text("Top View"))
        }
    }
}

struct TopView: View {
    @State private var viewTypeA = true

    let detailViewA = DynamicNavigationDestinationLink(id: \String.self) { data in
            ListA(passedData: data)
    }

    let detailViewB = DynamicNavigationDestinationLink(id: \String.self) { data in
            ListB(passedData: data)
    }

    var body: some View {
            List(0..<5) { item in
                NavigationLink(destination: ListC(passedData: "FROM ROW #\(item)")) {
                    HStack {
                        Text("Row #\(item)")
                        Spacer()
                        Text("edit")
                            .tapAction {
                                self.detailViewA.presentedData?.value = "FROM TAP ACTION Row #\(item)"
                        }
                    }
                }
            }.navigationBarItems(trailing: Button(action: {
                            self.detailViewB.presentedData?.value = "FROM PLUS CIRCLE"
            }, label: {
                    Image(systemName: "plus.circle.fill")
                }))
    }
}

struct ListA: View {
    let passedData: String

    var body: some View {
        VStack {
            Text("VIEW A")
            Text(passedData)
        }
    }
}

struct ListB: View {
    let passedData: String

    var body: some View {
        VStack {
            Text("VIEW B")
            Text(passedData)
        }
    }
}

struct ListC: View {
    let passedData: String

    var body: some View {
        VStack {
            Text("VIEW C")
            Text(passedData)
        }
    }
}

Much improved version (SwiftUI, iOS 13 beta 7)大大改进的版本(SwiftUI,iOS 13 beta 7)

The same solution works for dismissing Modals presented with the .sheet modifier.相同的解决方案适用于消除使用 .sheet 修饰符呈现的模态。

import SwiftUI

struct DetailView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var body: some View {
        Button(
            "Here is Detail View. Tap to go back.",
            action: { self.presentationMode.wrappedValue.dismiss() }
        )
    }
}

struct RootView: View {
    var body: some View {
        VStack {
            NavigationLink(destination: DetailView())
            { Text("I am Root. Tap for Detail View.") }
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            RootView()
        }
    }
}

improved version.改良版。 (Swift, iOS 13 beta 4) (斯威夫特,iOS 13 测试版 4)

class NavigationModel : BindableObject {
    var willChange = PassthroughSubject<Void, Never>()
    var presentedData: String? {
        didSet {
            willChange.send()
        }
    }
    func dismiss() { if presentedData != nil {
        presentedData = nil
    } }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            MasterView()
        }.environmentObject(NavigationModel())
    }
}

struct MasterView: View {

    @EnvironmentObject
    var navigationModel: NavigationModel
    var destinationLink = DynamicNavigationDestinationLink<String, String, DetailView>(id: \.self) { data in DetailView(data: data) }

    var body: some View {
        List(0..<10) { index in
            Button("I am root. Tap for more details of #\(index).") {
                self.navigationModel.presentedData = "#\(index)"
            }
        }
        .navigationBarTitle("Master")
        .onReceive(navigationModel.willChange) {
            self.destinationLink.presentedData?.value = self.navigationModel.presentedData
        }
    }
}

struct DetailView: View {
    @EnvironmentObject
    var model: NavigationModel

    let data: String

    var body: some View {
        Button("Here are details of \(data). Tap to go back.") {
            self.model.dismiss()
        }
        .navigationBarTitle("Detail \(data)")
    }
}

struct Empty : Hashable {
}


#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM