9

In Xcode beta 4 using PresentationLink gives the following warning: "'PresentationLink' is deprecated: Use .sheet modifier instead."

I'm assuming they mean some form of

func sheet<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, content: @escaping () -> Content) -> some View where Content : View

but I'm not to sure how to switch to this - in particular, the isPresented argument is confusing me. I know there's an Environment variable called isPresented, but isn't that for the current View, not the View that's going to be presented?

I'm mostly interested in this because I'm hoping this will fix the issue with PresentationLinks only working once (see swiftUI PresentaionLink does not work second time)

Can anyone supply a simple example of how to present a view now that PresentationLink is deprecated? E.g., convert the following to use the .sheet modifier:

  NavigationView {
        List {
            PresentationLink(destination: Text("Destination View")) {
                Text("Source View")
            }
        }
    }
KRH
  • 766
  • 1
  • 6
  • 8

4 Answers4

5

Below is an example that's as close as I could come to your example.

import SwiftUI

struct Testing : View {
    @State var isPresented = false

    var body: some View {
        NavigationView {
            List {
                Button(action: { self.isPresented.toggle() })
                    { Text("Source View") }
                }
            }.sheet(isPresented: $isPresented, content: { Text("Destination View") })
    }
}

This does indeed seem to resolve the bug you referenced about PresentationLinks not working the second time

Zain
  • 1,569
  • 1
  • 13
  • 19
  • I believe the `.sheet` parameter should be attached to the `Button` rather than the `List`, and `$isPresented` should be prepended with `self.` I had errors in my code until I made these adjustments. – Ben Jul 18 '19 at 16:46
  • @Ben If you attach the .sheet to the Button, you may experience this bug https://stackoverflow.com/a/57087399/3179416 – Zain Jul 18 '19 at 17:15
4

You should be able to update your code like so,

struct MainScreen: View {
    @State var shown = false

    var body: some View {

        VStack{
            Button(action: {
                self.shown.toggle()
            }) {
                Text("Press me to present")
            }
        }.sheet(isPresented: $shown) { () -> SecondScreen in

            return SecondScreen(dismissFlag: self.$shown)
        }


    }
}


struct SecondScreen: View {

    @Binding var dismissFlag: Bool

    var body: some View {

        VStack{
            Button(action: {

                self.dismissFlag = false

            }) {
                Text("Second screen, click to exit")
            }
        }


    }
}

In regards to the Environment variable isPresented, you could use that approach and you should be able to set isPresented?.value = false in the SecondScreen View, but I haven't been able to get that working in beta 4, though I've used that approach in beta 3 just fine.

MAVO
  • 153
  • 1
  • 10
2

I will use these code until the present method stable

UIApplication.shared.windows[0].rootViewController!.present(UIHostingController(rootView: view), animated: true, completion: nil)
UIApplication.shared.windows[0].rootViewController!.dismiss(animated: true, completion: nil)

(.sheet seems broken or hard to use when using VStack or List)

hstdt
  • 5,652
  • 2
  • 34
  • 34
0

I'd suggest to use Navigation Link

NavigationView {
  List {
    NavigationLink(
      destination: Text("Destination View")) {
        Text("Source View")
   }
  }
}

More details from this article