Xcode Previews break when using ScrollViewProxy + Preferences

I'm working on a horizontally scrollable header view. I'd like to implement the following behavior: when users tap on the left/rightmost header items, the header would scroll so they become fully visible. I am using a custom PreferenceKey to report the selected index:

struct SelectedTabPreference: PreferenceKey {
	static var defaultValue: Int = 0
	static func reduce(value: inout Int, nextValue: () -> Int) {}
}

Then in my view, I wrap my content inside a ScrollViewReader to scroll to the selected header:

struct ContentView: View {
	let tabs: [DrawerTab]
	@State private var selectedIndex: Int = 0
	
	var body: some View {
		ScrollViewReader { scrollProxy in
			ScrollView(.horizontal, showsIndicators: false) {
				TopTabView(options: tabs, selectedIndex: $selectedIndex)
					.padding(32)
					.background(Color.clear.preference(key: SelectedTabPreference.self, value: selectedIndex))
			}
			.onPreferenceChange(SelectedTabPreference.self) { value in
				let firstTabSelected = value == 0
				let lastTabSelected = value == tabs.count - 1
				guard firstTabSelected || lastTabSelected else { return }
				withAnimation {
					let anchor: UnitPoint = firstTabSelected ? UnitPoint(x: 0.1, y: 0) : UnitPoint(x: 0.9, y: 0)
					scrollProxy.scrollTo(tabs[value], anchor: anchor)
				}
			}
		}
	}
}

This works well when I run the app, but the Xcode Preview only shows a white screen. In fact, if I include this view as a subview in other views, their previews also break. The Preview only returns to life if I remove the programmatic scrolling:

scrollProxy.scrollTo(tabs[value], anchor: anchor)

I'm pretty sure this has to do with the ScrollViewProxy as my other Preference-based layouts work with Previews, but I don't know how to resolve the issue. Xcode Previews are an integral part of my workflow, and I'd like to avoid losing them if there's a chance.

Replies

Hi,

Sorry to hear you are having problems getting previews working. The best next step will be to file a feedback with diagnostics and a sample project so we can take a look.

Steps to generate helpful diagnostics for this case:

  1. Reproduce the issue
  2. Click the "Diagnostics" button in the error banner in Previews' Canvas area (or if the banner is missing you can use the menu: Editor > Canvas > Diagnostics)
  3. In the sheet that appears, click "Generate Report" in the bottom left of the sheet
  4. Attach (or make from the folder) the resulting zip file to the bug (will be named something like previews-diagnostics-0123456789.zip)

Please report back here with the feedback ID and I'll make sure it gets routed to the right team.

  • Thanks for the helpful comment. I've filed a feedback (FB13422931).

Add a Comment