Usé Gradient con un modificador .mask(_:) para implementar Text con un color de primer plano degradado en SwiftUI. Pero el texto siempre está en la parte superior de la vista. ¿Cómo puedo ponerlo en el centro de la vista?

Esta es mi implementación:

import SwiftUI

struct GradientText: View {
    var body: some View {
        LinearGradient(gradient: Gradient(colors: [.blue, .red, .orange]), 
                       startPoint: .leading, endPoint: .trailing)
            .mask(Text("Hello, world!")
                .font(.system(size: 40, weight: .bold, design: .rounded)))
            .padding()
    }
}

¿Y cómo se ve?

enter image description here

2
zvv 24 ago. 2020 a las 14:27

1 respuesta

La mejor respuesta

El problema es que LinearGradient está llenando todo el espacio que se le da. Si quita el mask, verá qué tan grande es. Le gustaría que fuera del tamaño del texto.

Estoy seguro de que hay una mejor manera de manejar esto, pero esto es lo que se me ocurrió. Al comenzar con el texto, podemos usar LinearGradient como overlay que coincidirá exactamente con el tamaño del texto.

struct GradientText: View {
    let text = Text("Hello World")
        .font(.system(size: 40, weight: .bold, design: .rounded))
    
    var body: some View {
        text
        .foregroundColor(.clear)
        .overlay(
            LinearGradient(gradient: Gradient(colors: [.blue, .red, .orange]),
                startPoint: .leading, endPoint: .trailing)
            .mask(text))
    }
}

Ampliando esta idea aún más, podría hacer que GradientText tome text y gradient como entradas para que pueda hacer esto fácilmente de forma repetida:

struct GradientText: View {
    let text: Text
    let gradient: LinearGradient
    
    init(text: Text, gradient: LinearGradient? = nil) {
        self.text = text
        self.gradient = gradient ?? LinearGradient(gradient: Gradient(colors: [.blue, .red, .orange]), startPoint: .leading, endPoint: .trailing)
    }
    
    var body: some View {
        text
        .foregroundColor(.clear)
        .overlay(
            gradient
            .mask(text))
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            GradientText(text: Text("Hello World")
                .font(.system(size: 40, weight: .bold, design: .rounded)))
            GradientText(text: Text("Goodnight World"), gradient: LinearGradient(gradient: Gradient(colors: [.green, .yellow, .orange]), startPoint: .leading, endPoint: .trailing))
        }
    }
}
2
vacawama 24 ago. 2020 a las 13:14