- Published on
SwiftUI-da VisualEffect ViewModifier'dan qanday foydalanish kerak
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
VisualEffect modifikatori iOS 17'da qo'shilgan β u GeometryReaderga muqobil, ammo faqat vizual effektlar uchun mo'ljallangan. GeometryReader ishlatsiz elementning o'lchami va ekrandagi joylashuviga qarab effektlar qo'llash imkonini beradi, va ko'p hollarda undan ham samaraliroq ishlaydi.
Talab: iOS 17+
Muammo: GeometryReader bilan
Aytaylik, matnning kengligi 200 pikseldan katta bo'lsa, grayscale qo'llashni xohlaymiz. GeometryReader bilan:
GeometryReader { geometry in
Text("Hello, World!")
.background(Color.red)
.padding()
.grayscale(geometry.size.width >= 200 ? 1 : 0)
}
.background(Color.green)
Muammo 1: GeometryReader standart bo'yicha ekranning to'liq kengligini egallaydi β green fon butun kenglikni qoplaydi, va geometry.size.width matnning emas, GeometryReaderning kengligi bo'ladi (masalan, 361 piksel).
Muammo 2: Har bir elementga GeometryReader qo'yish ilovani sekinlashtirishi mumkin.
Yechim: VisualEffect modifikatori
@available(iOS 17, *)
struct VisualEffectBootcamp: View {
var body: some View {
Text("Hello, World!")
.background(Color.red)
.padding()
.frame(width: 200)
.visualEffect { content, geometry in
content
.grayscale(geometry.size.width >= 200 ? 1 : 0)
}
}
}
visualEffect closure ikki parametr beradi:
contentβ shu elementning visual effect turi (oddiyViewemas,EmptyVisualEffect)geometryβ elementning o'zi haqidagiGeometryProxy(xuddiGeometryReaderdakidek)
Muhim nuance: content β bu EmptyVisualEffect turi, shuning uchun unga barcha modifikatorlarni qo'llab bo'lmaydi. Faqat quyidagilar ishlaydi:
blur, brightness, colorEffect, contrast, distortionEffect,
grayscale, hueRotation, offset, opacity, rotation3DEffect,
scaleEffect, saturation, transform va boshqalar
frame, foregroundColor kabi modifikatorlar ishlamaydi β ular uchun hamon GeometryReader ishlatish kerak.
Elementning koordinatasiga qarab effekt
geometry.frame(in: .global) orqali elementning ekrandagi joylashuvini olish mumkin:
Text("Hello, World!")
.padding()
.background(Color.red)
.visualEffect { content, geometry in
content
.grayscale(geometry.frame(in: .global).minY < 300 ? 1 : 0)
}
Element ekranning yuqorisida (minY < 300) bo'lsa β grayscale, pastda bo'lsa β rangli.
Animatsiya qo'shish
visualEffect ichida animatsiya o'z-o'zidan ishlamaydi β uni tashqaridan qo'shish kerak:
@State private var showSpacer: Bool = false
VStack {
if showSpacer { Spacer() }
Text("Hello, World!")
.padding()
.background(Color.red)
.visualEffect { content, geometry in
content
.grayscale(geometry.frame(in: .global).minY < 300 ? 1 : 0)
}
.onTapGesture {
showSpacer.toggle()
}
}
.animation(.easeIn, value: showSpacer) // tashqarida
.animation modifikatori visualEffect tashqarisida β VStack darajasida qo'llanilganda animatsiya ishlaydi.
Scroll view ichida parallax effekti
Bu β visualEffectning eng qulay ishlatish holati:
@available(iOS 17, *)
struct VisualEffectBootcamp: View {
var body: some View {
ScrollView {
VStack(spacing: 30) {
ForEach(0..<100) { index in
Rectangle()
.frame(width: 300, height: 200)
.frame(maxWidth: .infinity)
.background(Color.orange)
.visualEffect { content, geometry in
content
.offset(x: geometry.frame(in: .global).minY * 0.05)
}
}
}
}
}
}
Mantiq: Har bir to'rtburchakning minY qiymati β ekrandagi vertikal pozitsiyasi. * 0.05 koeffitsienti bilan bu qiymatni gorizontal offset'ga aylantiramiz. Yuqoridagi elementlar past qiymatga (kichik offset), pastdagi elementlar esa katta qiymatga (katta offset) ega bo'ladi β natijada aylantirib ko'rilganda chiroyli parallax effekti hosil bo'ladi.
Koeffitsiyentni 0.5ga oshirib kuchaytirish mumkin:
.offset(x: geometry.frame(in: .global).minY * 0.5)
Bu effekt GeometryReader bilan ham qilinishi mumkin edi, ammo visualEffect ancha silliqroq ishlaydi.
Qachon VisualEffect, qachon GeometryReader
| Holat | Tavsiya |
|---|---|
| Grayscale, blur, opacity, offset, scale asosida effekt | VisualEffect |
| Frame, foregroundColor o'zgartirish kerak | GeometryReader |
| ScrollView ichida silliq animatsiya | VisualEffect |
| iOS 16 va pastni qo'llab-quvvatlash kerak | GeometryReader |
Xulosa
visualEffect β GeometryReaderga engil, samaraliroq muqobil, ammo cheklangan:
- Faqat vizual modifikatorlar (blur, scale, offset va h.) ishlaydi
frame,foregroundColorkabi modifikatorlar ishlamaydi- iOS 17+ talab qiladi
Agar GeometryReader ishlatib, faqat vizual effektlar qo'llayotgan bo'lsangiz β visualEffectga o'ting. Aks holda GeometryReaderni saqlang.