Property Wrappers en Swift: @State, @Published y crear los propios

Un property wrapper es un struct (o clase) marcado con @propertyWrapper que expone una propiedad wrappedValue. El compilador lo inserta automáticamente en cada acceso a la propiedad que lo usa:

@propertyWrapper
struct Clamped {
    private var value: Int
    let range: ClosedRange

    var wrappedValue: Int {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }

    init(wrappedValue: Int, _ range: ClosedRange) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}

struct Jugador {
    @Clamped(0...100) var vida: Int = 100
}

var j = Jugador()
j.vida = 150
print(j.vida)  // 100 (clamped)
j.vida = -10
print(j.vida)  // 0

@State en SwiftUI

@State almacena un valor en el árbol de vistas de SwiftUI y provoca que la vista se redibuje cuando cambia:

import SwiftUI

struct ContadorView: View {
    @State private var cuenta = 0

    var body: some View {
        VStack {
            Text("(cuenta)")
            Button("Incrementar") { cuenta += 1 }
        }
    }
}

@Published y ObservableObject

import Combine

class ViewModel: ObservableObject {
    @Published var nombre: String = ""
    @Published var cargando: Bool = false

    func cargar() {
        cargando = true
        // ... trabajo asíncrono
        nombre = "Swift"
        cargando = false
    }
}

projectedValue: el valor proyectado con $

@propertyWrapper
struct UserDefault {
    let key: String
    let defaultValue: T
    var wrappedValue: T {
        get { UserDefaults.standard.object(forKey: key) as? T ?? defaultValue }
        set { UserDefaults.standard.set(newValue, forKey: key) }
    }
    var projectedValue: String { key }  // acceso con $nombrePropiedad
}

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP