Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call ScrollView's scrollTo from Observer or external View

Tags:

swiftui

I am trying to reset my ScrollView when the user selects a tab. The problem is all the tutorials are for buttons nested inside the ScrollView. My ScrollView is completely separate from where I need to tap to reset the ScrollView.

I found this tutorial - https://www.hackingwithswift.com/forums/swiftui/have-a-button-outside-of-scrollviewreader-be-able-to-scroll-the-scrollview-to-a-position/2741

Yet I get the error "Cannot find proxy in scope".

   @EnvironmentObject var global: GlobalObserver    
   return ScrollView {
          ScrollViewReader { (proxy: ScrollViewProxy) in
             EmptyView()
          }.onChange(of: self.global.resetScroll){ resetScroll in
                if (resetScroll){
                    proxy.scrollTo(0)
                    self.global.resetScroll = false
                }
            }

If anyone knows an easier implementation to setting ScrollView position outside of the View I would be happy to hear it.

like image 976
C. Skjerdal Avatar asked Oct 21 '25 22:10

C. Skjerdal


1 Answers

Adapting the example from the link in the question, your code can look like this:

struct ContentView: View {
    @State private var scrollTarget: Int?

    var body: some View {
        Button("Reset") {
            scrollTarget = 0
        }
        ScrollViewReader { proxy in
            ScrollView {
                VStack {
                    ForEach(0...50, id: \.self) {
                        Text("\($0)")
                    }
                }
            }
            .onChange(of: scrollTarget) { target in
                if let target = target {
                    scrollTarget = nil
                    withAnimation {
                        proxy.scrollTo(target)
                    }
                }
            }
        }
    }
}

If needed, you can move scrollTarget to an ObservableObject and call it from outside the view:

class GlobalObserver: ObservableObject {
    @Published var scrollTarget: Int?
}

struct ContentView: View {
    @EnvironmentObject var global: GlobalObserver

    var body: some View {
        ScrollViewReader { proxy in
            ScrollView {
                VStack {
                    ForEach(0...50, id: \.self) {
                        Text("\($0)")
                    }
                }
            }
            .onChange(of: global.scrollTarget) { target in
                if let target = target {
                    global.scrollTarget = nil
                    withAnimation {
                        proxy.scrollTo(target)
                    }
                }
            }
        }
    }
}
like image 160
pawello2222 Avatar answered Oct 24 '25 12:10

pawello2222