Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

857
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda