10

I have a ContentView written in swiftUI as simple as below.

var body: some View {
    
    NavigationView {
        List {
            Section {
                PresentationLink(destination: Text("new Profile")) {
                    Text("new Profile")
                }
            }
        }
    }

everything is good first time I tap on new profile but when I close the modal and try to tap again, it does not work.

is it a bug or a feature?

Kaushik Makwana
  • 142
  • 1
  • 14
Congruent Tech. UG
  • 1,408
  • 2
  • 12
  • 21
  • 1
    `PresentationLink` was renamed from `PresentationButton` in beta 3. And yes, it *may* be a bug: https://stackoverflow.com/questions/56524033/swiftui-tutorial-presentationbutton-bug I haven't had this issue but my `PresentationLink` isn't embedded in a `NavigationView`. (1) If you can, test your code without a `NavigationView` and (2) implement the workaround in the linked answer if needed. –  Jul 16 '19 at 21:02
  • A couple of days ago I found the same issue in one App (PresentationLink not working the second time), but not in another. Both Apps use NavigationViews, so I don't think that's it. I finally isolated it to the PresentationLink being inside a List or Form. Try commenting out your List and it should work, but obviously it will not look correct. I too expect that this is a bug and it's not fixed in Beta 4. – Chuck H Jul 18 '19 at 00:10
  • 1
    This is a bug in beta 4. `View.sheet` seems to malfunction whilst embedded in a `List` or `NavigationView`. I urge you to file a bug report, as this may go unnoticed and therefore unfixed by the time the GM is released. – Vatsal Manot Jul 21 '19 at 09:01
  • 3
    This seems to still be happening in Xcode 11 beta 5. Or did anyone else have more luck than I? – Adam Bolcsfoldi Jul 31 '19 at 21:20

1 Answers1

13

PresentationLink has been deprecated in Xcode 11 beta 4 in favor of .sheet, which seems to solve the issue.

Added improved presentation modifiers: sheet(isPresented:onDismiss:content:), actionSheet(isPresented:content:), and alert(isPresented:content:) — along with isPresented in the environment — replace the existing presentation(_:), Sheet, Modal, and PresentationLink types. (52075730)

If you change the code to .sheet like below:

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") })
    }
}

You will then be able to use the modal as many times as you like instead of just once.

GIF showing that the modal can be brought up and dismissed several times instead of just once

EDIT: After implementing this in a real scenario, I've found that the underlying bug still seems to exist if you put .sheet inside of the List. If you follow the code example above, you won't experience this issue but in a real scenario where you're using a List, you're probably going to want information about the particular item that was selected passed in to the modal. In that case, you're going to need to pass information about the selection via a @State var or some other means. Below is an example:

import SwiftUI

struct Testing : View {
    @State var isPresented = false
    @State var whichPresented = -1

    var body: some View {
        NavigationView {
            List {
                ForEach(0 ..< 10) { i in
                    Button(action: {
                            self.whichPresented = i
                            self.isPresented.toggle()
                })
                        { Text("Button \(i)") }
                    }
                }
            }.sheet(isPresented: $isPresented, content: { Text("Destination View \(self.whichPresented)") })
    }
}
Zain
  • 1,569
  • 1
  • 13
  • 19
  • 1
    I have also installed Beta 4 and replaced all of my PresentationLink's with .sheet modifiers. The modal sheet will now open a second time after swiping down to dismiss the modal. However, with no changes to my Modal View, it no longer dismisses programmatically by setting the isPresented environment var to false in response to a Button tap like it used to do. Are you able to dismiss the modal programmatically? – Chuck H Jul 18 '19 at 19:57
  • @ChuckH Can you post your code as a separate question? I'm able to set isPresented programmatically within the sheet `Button(action: { self.isPresented.toggle() }) { Text("Done") }` – Zain Jul 19 '19 at 14:44
  • yes I also have the problem of not being able to dismiss programatically via isPresented. – Congruent Tech. UG Jul 21 '19 at 15:28
  • 1
    This issue also happens inside of a Scrollview – Andre Carrera Jul 25 '19 at 02:05
  • There is another form of .sheet. If it works like alert then assigning to an item triggers the display and dismissing the sheet removes the item. It seems a better fit for your case. – Michael Salmon Aug 06 '19 at 18:33
  • 1
    I can confirm this bug @AndreCarrera mentioned still exists in Beta 5/6: See https://stackoverflow.com/questions/57546433/scrollview-breaks-sheet-representation – grahan Aug 20 '19 at 18:47
  • Could you please fix the code indentation because it makes things hard to read/understand. (The 8-spaces between two subsequent `}` show there's something wrong.) – meaning-matters Oct 05 '19 at 12:10