Posts

Post not yet marked as solved
1 Replies
314 Views
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.
Posted Last updated
.