0

I've included stubbed code samples. I'm not sure how to get this presentation to work. My expectation is that when the sheet presentation closure is evaluated, aDependency should be non-nil. However, what is happening is that aDependency is being treated as nil, and TheNextView never gets put on screen.

How can I model this such that TheNextView is shown? What am I missing here?

struct ADependency {} struct AModel { func buildDependencyForNextExperience() -> ADependency? { return ADependency() } } struct ATestView_PresentationOccursButNextViewNotShown: View { @State private var aDependency: ADependency? @State private var isPresenting = false @State private var wantsPresent = false { didSet { aDependency = model.buildDependencyForNextExperience() isPresenting = true } } private let model = AModel() var body: some View { Text("Tap to present") .onTapGesture { wantsPresent = true } .sheet(isPresented: $isPresenting, content: { if let dependency = aDependency { // Never executed TheNextView(aDependency: dependency) } }) } } struct TheNextView: View { let aDependency: ADependency init(aDependency: ADependency) { self.aDependency = aDependency } var body: some View { Text("Next Screen") } } 
5
  • You want to initialise aDependency on state change? Is that a required condition? Commented Feb 27, 2021 at 20:27
  • @TusharSharma correct! Yes Commented Feb 27, 2021 at 20:29
  • why not do it in initialiser? When you tap on text, you can just toggle isPresented to true, and sheet will be invoked. As you already initialised dependency while initialisation it won’t be nil? Isn’t that what you want? Commented Feb 27, 2021 at 20:32
  • @TusharSharma the dependency isn’t computer at compile time and is computed after the user clicks on a button Commented Feb 27, 2021 at 20:35
  • what about doing-: "TheNextView(aDependency:model.buildDependencyForNextExperience())”. Model is providing object, so why not pass it directly when presentation sheet? You can also remove wantsPresent and adependency state properties. Commented Feb 27, 2021 at 21:21

1 Answer 1

3

This is a common problem in iOS 14. The sheet(isPresented:) gets evaluated on first render and then does not correctly update.

To get around this, you can use sheet(item:). The only catch is your item has to conform to Identifiable.

The following version of your code works:

struct ADependency : Identifiable { var id = UUID() } struct AModel { func buildDependencyForNextExperience() -> ADependency? { return ADependency() } } struct ContentView: View { @State private var aDependency: ADependency? private let model = AModel() var body: some View { Text("Tap to present") .onTapGesture { aDependency = model.buildDependencyForNextExperience() } .sheet(item: $aDependency, content: { (item) in TheNextView(aDependency: item) }) } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.