scrolling to top of a TabView child feature using ScrollViewProxy #2607
Unanswered
majelbstoat
asked this question in
Q&A
Replies: 1 comment
-
I went with creating my own binding, and it works, though I admit, I'm a little hazy on whether it's a reasonable approach: @Reducer
struct RootFeature {
@ObservableState
struct State {
var selectedTab = Tab.home
var questions = QuestionsFeature.State()
}
enum Action {
case tabSelected(Tab, ScrollViewProxy)
}
enum Tab {
case questions
case other
}
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case let .tabSelected(tab, proxy):
if state.selectedTab == tab {
if tab == .questions {
if state.questions.path.isEmpty {
// scroll to top
withAnimation {
proxy.scrollTo(ScrollAnchor.questionTop, anchor: .bottom)
}
} else {
// pop to root
state.questions.path.removeAll()
}
}
} else {
state.selectedTab = tab
}
return .none
}
}
}
}
struct RootView: View {
@State var store: StoreOf<RootFeature>
func createTabViewBinding(proxy: ScrollViewProxy) -> Binding<RootFeature.Tab> {
Binding(
get: { store.state.selectedTab },
set: { selectedTab in
store.send(.tabSelected(selectedTab, proxy))
}
)
}
var body: some View {
ScrollViewReader { proxy in
TabView(selection: createTabViewBinding(proxy: proxy), content: {
QuestionsView().tag(Tag.questions)
OtherView().tag(Tag.other)
}
}
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I have a pretty classic TabView navigation, where I'd like a second tap on a tab to pop to the root of the feature, and a third tap to scroll to the top of the view. I'm currently using the provided
sending
method to create the selection binding:which works great to switch between tabs. I have a tabSelected action in my reducer which sets the desired state:
To do scroll to top, I need a ScrollViewProxy which I can get in the view:
However, I can't find an easy way to get that proxy to the reducer. I looked into rewriting or extending
sending
to take a proxy as a second parameter, and send that as part of the action, but it involves a fileprivate wrappedValue. (I don't even quite know if this approach would work).Things I'm wondering:
Beta Was this translation helpful? Give feedback.
All reactions