- Published on
Swiftda Property Wrappers
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Property Wrapper β property ga "xulq-atvor" qo'shish usuli. SwiftUI da har kuni ishlatiladigan @State, @Published, @AppStorage, @Binding β bularning hammasi property wrapper. O'zingiz ham yaratishingiz mumkin β qiymatni cheklash, tekshirish, avtomatik saqlash kabi logikalarni bitta joyda yozib, ko'p property larda qayta ishlatish.
Property Wrapper ning asosiy tushunchalari: wrappedValue β foydalanuvchi ko'radigan va o'zgartiradigan asosiy qiymat. projectedValue ($ prefiksi bilan) β qo'shimcha ma'lumot (masalan, @State da $name Binding qaytaradi).
Property Wrapper yaratish
@propertyWrapper atributi struct yoki class ni property wrapper sifatida belgilaydi. wrappedValue property majburiy. Quyida qiymatni belgilangan oraliqda cheklaydigan wrapper ko'rsatilgan.
// βββββββββββββββββββββββββββββββββββββββ
// @PROPERTYWRAPPER β o'z wrapper imizni yaratamiz
// Bu wrapper qiymatni 0...100 oraliqda cheklaydi
// βββββββββββββββββββββββββββββββββββββββ
@propertyWrapper
struct Chegaralangan {
private var qiymat: Int
private let min: Int
private let max: Int
// wrappedValue β asosiy qiymat (tashqaridan ko'rinadigan)
var wrappedValue: Int {
get { qiymat }
set { qiymat = Swift.min(Swift.max(newValue, min), max) }
// newValue min dan kichik bo'lsa min, max dan katta bo'lsa max
}
init(wrappedValue: Int, min: Int, max: Int) {
self.min = min
self.max = max
// Init da ham cheklash
self.qiymat = Swift.min(Swift.max(wrappedValue, min), max)
}
}
// Ishlatish β @ bilan
struct OyinBotirma {
@Chegaralangan(min: 0, max: 100) var hayot = 100
@Chegaralangan(min: 0, max: 10) var daraja = 1
}
var botir = OyinBotirma()
botir.hayot = 150 // 100 ga chegaralanadi (max)
print(botir.hayot) // 100
botir.hayot = -20 // 0 ga chegaralanadi (min)
print(botir.hayot) // 0
botir.daraja = 15 // 10 ga chegaralanadi
print(botir.daraja) // 10
projectedValue β $ bilan qo'shimcha ma'lumot
projectedValue β $ prefiksi bilan chaqiriladigan qo'shimcha qiymat. Masalan, @State var ism = "" da $ism Binding<String> qaytaradi. O'z wrapper ingizda projectedValue ni qo'shib, qo'shimcha ma'lumot berish mumkin.
// βββββββββββββββββββββββββββββββββββββββ
// PROJECTEDVALUE β $ prefiksi bilan chaqiriladigan qo'shimcha qiymat
// βββββββββββββββββββββββββββββββββββββββ
@propertyWrapper
struct BoshHarfli {
private var matn: String
var wrappedValue: String {
get { matn }
set { matn = newValue.capitalized }
// .capitalized β har so'zning bosh harfi katta
}
// $ bilan chaqiriladi β asl qiymatni ko'rsatadi
var projectedValue: String {
matn.uppercased() // HAMMASI KATTA HARF
}
init(wrappedValue: String) {
self.matn = wrappedValue.capitalized
}
}
struct Profil {
@BoshHarfli var ism = "ali valiyev"
}
var profil = Profil()
print(profil.ism) // "Ali Valiyev" (wrappedValue)
print(profil.$ism) // "ALI VALIYEV" (projectedValue)
// SwiftUI da $state β Binding qaytaradi
// @State var ism = "" β $ism = Binding<String>
@State va @Published qanday ishlaydi
SwiftUI ning @State va Combine ning @Published aslida property wrapper. @State qiymat o'zgarganda View ni qayta chizadi. @Published qiymat o'zgarganda ObservableObject orqali barcha kuzatuvchilarga signal yuboradi. Quyida ularning soddalashtirilgan ishlash tartibi ko'rsatilgan.
// βββββββββββββββββββββββββββββββββββββββ
// @STATE β soddalashtirilgan ko'rinish
// (Apple ning haqiqiy implementatsiyasi murakkab)
// βββββββββββββββββββββββββββββββββββββββ
// @State aslida shunday ishlaydi:
// 1. wrappedValue β qiymatni o'qish/yozish
// 2. projectedValue ($) β Binding qaytaradi
// 3. Qiymat o'zgarganda β SwiftUI View ni qayta chizadi
// βββββββββββββββββββββββββββββββββββββββ
// @PUBLISHED β soddalashtirilgan ko'rinish
// βββββββββββββββββββββββββββββββββββββββ
// @Published aslida shunday ishlaydi:
// 1. wrappedValue β qiymatni o'qish/yozish
// 2. projectedValue ($) β Combine Publisher qaytaradi
// 3. willSet da β ObservableObject.objectWillChange signal yuboradi
// Misol: @Published ni tushunish
import Combine
@propertyWrapper
struct XabardorQiymat<T> {
private var qiymat: T
// Publisher β qiymat o'zgarganda signal
let publisher = PassthroughSubject<T, Never>()
var wrappedValue: T {
get { qiymat }
set {
qiymat = newValue
publisher.send(newValue) // Kuzatuvchilarga xabar
}
}
var projectedValue: PassthroughSubject<T, Never> {
publisher
}
init(wrappedValue: T) {
self.qiymat = wrappedValue
}
}
Amaliy misollar
Property Wrapper ning chinakam kuchi amaliy misollarda namoyon bo'ladi. @UserDefaultsda β qiymatni avtomatik UserDefaults ga saqlash. @Tozalangan β matn atrofidagi bo'shliqlarni avtomatik olib tashlash. Bir marta yozib, ko'p joyda ishlatish mumkin.
// βββββββββββββββββββββββββββββββββββββββ
// @USERSDEFAULTS β avtomatik saqlash
// βββββββββββββββββββββββββββββββββββββββ
@propertyWrapper
struct UserDefaultsda<T> {
let kalit: String
let boshlangich: T
var wrappedValue: T {
get { UserDefaults.standard.object(forKey: kalit) as? T ?? boshlangich }
set { UserDefaults.standard.set(newValue, forKey: kalit) }
}
}
struct Sozlamalar {
@UserDefaultsda(kalit: "qorong'uRejim", boshlangich: false)
var qorong'uRejim: Bool
@UserDefaultsda(kalit: "tilKodi", boshlangich: "uz")
var til: String
}
var soz = Sozlamalar()
soz.qorong'uRejim = true // UserDefaults ga avtomatik saqlandi
// βββββββββββββββββββββββββββββββββββββββ
// @TRIMMED β bo'shliqlarni olib tashlash
// βββββββββββββββββββββββββββββββββββββββ
@propertyWrapper
struct Tozalangan {
private var matn: String = ""
var wrappedValue: String {
get { matn }
set { matn = newValue.trimmingCharacters(in: .whitespacesAndNewlines) }
}
init(wrappedValue: String) {
self.wrappedValue = wrappedValue
}
}
struct RoyxatdanOtish {
@Tozalangan var email = ""
@Tozalangan var ism = ""
}
var forma = RoyxatdanOtish()
forma.email = " ali@mail.com "
print(forma.email) // "ali@mail.com" β bo'shliqlar olib tashlandi
π― Topshiriq
@Parolga property wrapper yarating: kamida 8 ta belgi, kamida 1 ta raqam bo'lishi kerak. Agar qoida buzilsa β eski qiymatni saqlang. projectedValue sifatida Bool (parol kuchli/kuchsiz) qaytaring. $parol bilan tekshiring.