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

198
Vistas
¿Cómo asignar modificadores predeterminados a una vista de SwiftUI?

Estoy tratando de crear vistas personalizadas reutilizables que se puedan personalizar más adelante. Idealmente, podría definir modificadores predeterminados como Color, Fuente, etc. que las Vistas tendrían sin ninguna personalización, pero permitiría que estos se sobrescriban fácilmente con modificadores adicionales que se usen más adelante.

Por ejemplo, si tuviera la vista personalizada:

 struct MyCustomTextField: View { @Binding var text: String var body: some View { HStack { Image(systemName: "envelope").foregroundColor(.gray) TextField("", text: $text) .foregroundColor(.gray) .font(.system(.title)) } } }

La vista tendría un color de primer plano gris predeterminado y TextField tendría una fuente de título. Pero ahora, si quisiera reutilizar esta vista y personalizarla para mi caso de uso específico, es posible que desee anular estos modificadores de la siguiente manera:

 struct ContentView: View { @State var text = "hello" var body: some View { MyCustomTextField(text: $text) .foregroundColor(.blue) .font(.system(.body)) } }

Pero estos modificadores externos no son efectivos ya que los modificadores internos tienen prioridad.

¿Cuál es la mejor manera de crear vistas personalizadas para poder definir modificadores predeterminados para sus contenidos pero poder anular esos valores predeterminados más adelante?

Gracias

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Siempre debemos recordar que las vistas de SwiftUI son tipos de valor, por lo tanto, no puede cambiarlas después de la inicialización como lo haría en UIKit. Una forma posible sería inyectarlo en la inicialización. Pero si desea hacerlo ajustable después de la inicialización (por ejemplo, para cambiar el color al presionar algún otro botón), use el mecanismo de vinculación:

Agregue un @Binding a su MyCustomTextField y use su valor en el modificador de color de primer plano.

 struct MyCustomTextField: View { @Binding var text: String @Binding var foregroundColor: Color var body: some View { HStack { Image(systemName: "envelope").foregroundColor(.gray) TextField("", text: $text) .foregroundColor(foregroundColor) .font(.system(.title)) } } }

y luego en la vista del cliente puede hacer lo siguiente:

 struct MyView: View { @State var myText: String = "" @State var hasSpecialColor: Bool = false var foregroundColor: Binding<Color> { return Binding<Color>(get: { return hasSpecialColor ? Color.red : Color.black }, set: { newValue in hasSpecialColor = newValue == Color.red }) } var body: some View { VStack { Text("Some Header Text") MyCustomTextField(text: $myText, foregroundColor: foregroundColor) Button("click to toggle color") { hasSpecialColor.toggle() } } } }

ahora, cada vez que haga clic en el botón, alternará hasSpecialColor (que es @State ) y, por lo tanto, la vista se representará y el valor de @Binding de primer plano cambiará en consecuencia.

over 4 years ago · Santiago Trujillo Denunciar

0

Puede encontrar la Font establecida por el modificador de font más cercano en el entorno, para que pueda leerla y proporcionar un valor predeterminado como este:

 struct MyCustomTextField: View { @Binding var text: String @Environment(\.font) var envFont: Font? var body: some View { HStack { Image(systemName: "envelope").foregroundColor(.gray) TextField("", text: $text) .foregroundColor(.gray) .font(envFont ?? .system(.title)) } } }

Desafortunadamente, el modificador de color de foregroundColor no almacena su configuración en una propiedad de entorno (pública), por lo que debe seguir una ruta diferente. Una forma es proporcionar un modificador directamente en su vista personalizada, como esta:

 struct MyCustomTextField: View { @Binding var text: String var _myColor: Color = .gray @Environment(\.font) var envFont: Font? func myColor(_ color: Color) -> Self { var copy = self copy._myColor = color return copy } var body: some View { HStack { Image(systemName: "envelope").foregroundColor(.gray) TextField("", text: $text) .foregroundColor(_myColor) .font(envFont ?? .system(.title)) } } }

Luego puede usar el modificador myColor directamente en un MyCustomTextField como este:

 PlaygroundPage.current.setLiveView( MyCustomTextField(text: .constant("hello")) .myColor(.red) .padding() .font(.body) )

Pero no puede usarlo en ninguna vista envolvente o después de cualquier modificador no específico MyCustomTextField . Por ejemplo, esto no funcionará:

 PlaygroundPage.current.setLiveView( MyCustomTextField(text: .constant("hello")) .padding() .myColor(.red) // Error: Value of type 'some View' has no member 'myColor' .font(.body) )

Si desea que eso funcione, debe almacenar el color personalizado en el entorno, así:

 struct MyColor: EnvironmentKey { static var defaultValue: Color? { nil } } extension EnvironmentValues { var myColor: Color? { get { self[MyColor.self] } set { self[MyColor.self] = newValue } } } extension View { func myColor(_ color: Color?) -> some View { return self.environment(\.myColor, color) } } struct MyCustomTextField: View { @Binding var text: String @Environment(\.myColor) var envColor: Color? @Environment(\.font) var envFont: Font? var body: some View { HStack { Image(systemName: "envelope").foregroundColor(.gray) TextField("", text: $text) .foregroundColor(envColor ?? .gray) .font(envFont ?? .system(.title)) } } }

Y luego puede usar el modificador myColor en cualquier vista, y se aplicará a todas las subvistas adjuntas:

 PlaygroundPage.current.setLiveView( MyCustomTextField(text: .constant("hello")) .padding() .myColor(.red) .font(.body) )
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