Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

856
Views
SwiftUI: onChange con @Binding desde la vista exterior

Actualizado para proporcionar un ejemplo reproducible completo.

Tengo una vista MainView con dos subvistas, MainTextView y TableOfContentsView . Quiero seleccionar un elemento en TableOfContentsView que desencadena un cambio de posición de desplazamiento en MainTextView .

Tengo un @State var scrollPosition: Int en MainView que se pasa a un @Binding var scrollPosition: Int en MainTextView . Aquí está el código para mis 3 vistas.

 struct MainView: View { @State private var showingToc = false @State private var scrollPosition = 0 var body: some View { VStack(alignment: .leading) { Text("Table of Contents (chapter \(scrollPosition + 1))") .onTapGesture { showingToc = !showingToc } Divider() if showingToc { TableOfContentsView( onChapterSelected: { chapter in scrollPosition = chapter showingToc = false } ) } else { MainTextView(scrollPosition: $scrollPosition) } } } }
 struct TableOfContentsView: View { var onChapterSelected: (Int) -> Void var body: some View { ScrollView { VStack { ForEach(0 ..< 20) { i in Text("Chapter \(i + 1)") .onTapGesture { onChapterSelected(i) } } } } } }
 struct MainTextView: View { let lorumIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." @Binding var scrollPosition: Int @State private var scrollProxy: ScrollViewProxy? = nil var body: some View { ScrollView { ScrollViewReader { proxy in VStack(alignment: .leading) { ForEach(0 ..< 20) { i in VStack(alignment: .leading) { Text("Chapter \(i + 1)") .frame(maxWidth: .infinity, alignment: .center) .padding(.top) Text(lorumIpsum) .font(.system(size: 18, design: .serif)) .padding(.top) } .padding(.bottom, 20) .id(i) } } .padding(.leading) .padding(.trailing) .onAppear { scrollProxy = proxy } } } .onChange(of: scrollPosition) { target in scrollProxy?.scrollTo(target, anchor: .top) } } }

Mi función .onChange nunca se llama: si coloco un punto de interrupción dentro, nunca llega al punto de interrupción. ¿Que me estoy perdiendo aqui? ¿Cómo observo un @Binding que se cambia desde fuera de la vista?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

No se llamará a .onChange porque MainTextView no existe cuando showingToc = true debido al bloque condicional:

 if showingToc { TableOfContentsView(onChapterSelected: { chapter in scrollPosition = chapter showingToc = false } ) } else { MainTextView(scrollPosition: $scrollPosition) }

Es posible que desee considerar mostrar TOC como una superposición. Pero para que su código actual funcione, debe llamar a proxy.scrollTo en su .onAppear de MainTextView :

 .onAppear { scrollProxy = proxy scrollProxy?.scrollTo(scrollPosition, anchor: .top) }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!