Sheet Present And Load with Placeholders

Hi,

I'm currently implementing functionality similar to that shown in the 03-Navigation-Sheet-PresentAndLoad case study, however in my particular case I'd like to do something more complicated than showing an activity indicator while the optional store is nil.

Some context would likely help:

  • Users navigating a list of cells, each one an ItemSummary
  • On selection, present a sheet and make a network request to load ItemDetails
  • ItemSummary contains some data that is relevant for the sheet (ex. Item Name, Price etc.) but is missing some of it.
  • While loading, the sheet should show what data it can, while showing activity indicators in nested views that must wait for the ItemDetails
  • From the sheet, users can perform various actions related to the Item, and thus it would be preferable to have it's own store (with State/Action/Environment)

None of the above was particularly challenging - I made use of the same approach shown in the case study, but instead of an activity indicator for the else case of my IfLetStore I passed an ItemPlaceholderView initialized with the relevant ItemSummary.

What was challenging was trying to get SwiftUI animations to work with this approach - even if the structure of my ItemPlaceholderView and ItemDetailsView are practically identical, SwiftUI treats them as unrelated views and just swaps between them. Ideally I would like any of the nested views that rely on data from ItemDetails to smoothly animate from activity indicators to the relevant info once ItemDetails loads.

Ultimately I was able to accomplish the desired effect by getting rid of IfLetStore in the sheet presentation, and instead having something like the following for the sheet's state:

struct State {
var summary: ItemSummary
var details: ItemDetails?
}

Then I have a single ItemDetailsView that uses if/else statements or map to handle any dynamic subviews, while just displaying static data from the summary, like so:

WithViewStore(store) { viewStore in
	Text(viewStore.summary.name)

	if viewStore.details == nil {
		ActivityIndicator()
	} else {
		viewStore.details.map { SomeNestedView(foo: $0.foo) }
	}
}

This works, and allows for the slick SwiftUI animations that I'm looking for, but doesn't feel like the right way to do things - a big reason for the uneasiness is that my "Details" store can be sent actions, even though the details aren't loaded (many if not all of the actions will require information that only ItemDetails contain). I essentially have a store that begins in an invalid state, which increases the surface area I must test. Is there some way to leverage IfLetStore or a similar mechanism to avoid this, while still getting animations at the granularity I'm looking for?

Thank you for any help you can provide - and if more details are needed I'm happy to provide them.

1 Like

I'm also interested in this use case! Does anyone else with more experience with SCA (or TCA? What should I be using?) have some thoughts to share? Thanks!