Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

327
Visualizações
¿Cómo usar las propiedades @State y @Environment en una estructura que puede producir una vista pero no es una vista?

Estoy tratando de crear un estilo de vista para personalizar una vista personalizada de SwiftUI que estoy desarrollando. Declaré un protocolo con una función makeBody , almaceno el estilo como una propiedad @State para que pueda actualizarse y llamo a makeBody desde dentro de una vista. Esta técnica sigue de cerca lo que ya hace SwiftUI, pero hay una cosa que no puedo entender.

Problema

Hay un comportamiento importante que tienen los estilos de vista propios que no puedo replicar: usar @State , @Environment o cualquier otro contenedor de propiedades de SwiftUI dentro del estilo de vista personalizado.

Por ejemplo, puedo implementar el siguiente ButtonStyle personalizado que solo muestra el valor del esquema de color actual como el contenido del botón.

 struct MyButtonStyle: ButtonStyle { @Environment(\.colorScheme) var colorScheme func makeBody(configuration: Configuration) -> some View { Text(String(describing: colorScheme)) } } struct MyView: View { var body: some View { Button("foo", action: {}).buttonStyle(MyButtonStyle()) } }

Cuando obtengo una vista previa de MyView con un esquema de color preferido .dark , la propiedad colorScheme de MyButtonStyle se actualiza, se vuelve a llamar a la función makeBody y el texto dice "oscuro". Todo esto es lo esperado.

Ahora, echemos un vistazo al estilo de vista personalizado que creé.

 struct MyCustomStyle /* : CustomStyle */ { @Environment(\.colorScheme) var colorScheme @ViewBuilder func makeBody(configuration: CustomStyleConfiguration) -> some View { Text(String(describing: colorScheme)) } } struct MyView: View { @State var style = MyCustomStyle() var body: some View { style.makeBody(configuration: .init()) } }

En el escenario anterior, cuando obtengo una vista previa de MyView con un esquema de color preferido .dark , la propiedad colorScheme no se actualiza y el texto dice "claro" aunque el color de primer plano de la etiqueta haya captado correctamente el cambio.

Pregunta

¿Cómo hacer que las propiedades @State y @Environment funcionen en el estilo de vista personalizado, tal como funcionan en ButtonStyle y en las vistas, sin introducir ningún modelo en la implementación de la función makeBody ?

Estoy seguro de que es posible porque todos los estilos de vista propios ya admiten esto, sin estilos que se ajusten a View y sin que implementen la API privada _makeView que agrega manualmente dependencias al gráfico de SwiftUI (al menos de acuerdo con la interfaz del módulo de SwiftUI ).

Lo que intenté que no funcionó

Intenté inicializar el estilo de vista dentro de un body computable de una vista que envuelve MyView . Eso tampoco funciona.

 struct ContentView: View { var body: some View { MyView(style: MyCustomStyle()) } }

Respuestas inaceptables

Envolver el valor de retorno de la función makeBody personalizada en una vista separada, con la propiedad colorScheme como parte de esa vista, es una solución alternativa conocida que da como resultado un comportamiento correcto. Las respuestas que sugieran esto como una solución alternativa no serán aceptadas porque esta pregunta trata de evitar eso .

No se aceptarán las respuestas que digan que es imposible usar @Environment o @State fuera de un tipo conforme a View (porque es posible, consulte ButtonStyle ), a menos que puedan probar que la API privada es lo que impulsa esto.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

No tenemos acceso a la EnvironmentKey que corresponda con ColorScheme , pero su defaultValue debe ser light . Es por eso que nunca puede obtener un valor, fuera de una vista. Pero su tipo nunca se proporcionará con EnvironmentValues a menos que sea View , ViewModifier , ButtonStyle , ... Apple en realidad no ofrece una lista exhaustiva de protocolos que se consideran "parte de la jerarquía de vistas".

Pero si no se ajusta a uno de ellos, entonces es necesario confiar no en el entorno, sino en la inyección de dependencia. P.ej

 struct MyCustomStyle { init(environment: EnvironmentValues) { colorScheme = environment.colorScheme } private let colorScheme: ColorScheme @ViewBuilder func makeBody() -> some View { Text(String(describing: colorScheme)) } }
 struct ContentView: View { @Environment(\.self) private var environment var style: MyCustomStyle { .init(environment: environment) } var body: some View { style.makeBody() } }

Su pregunta también menciona State , pero no proporcionó un ejemplo. Probablemente solo necesite ajustarse a DynamicProperty para lo que sea que esté haciendo con State .

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda