- Published on
SwiftUI-da MagnificationGesture-dan qanday foydalanish kerak
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
MagnificationGesture nima
MagnificationGesture β bu iPhone-dagi xaritada yoki Instagram-da rasmda ikki barmog'ingizni ochib-yopib kattalashtirish/kichraytirish gesture-i. SwiftUI-da buni istalgan elementga qo'shish mumkin.
Yangi fayl yaratish
MagnificationGestureBootcamp nomli yangi SwiftUI View fayl yaratamiz.
Oddiy misol
@State private var currentAmount: CGFloat = 0
var body: some View {
Text("Hello, World!")
.font(.title)
.padding(40)
.background(Color.red)
.cornerRadius(10)
.scaleEffect(1 + currentAmount)
.gesture(
MagnificationGesture()
.onChanged { value in
currentAmount = value - 1
}
)
}
.gesture(MagnificationGesture())β gesture-ni elementga qo'shish usuli. Oldingi videodagiLongPressGestureo'rniga bu yerdaMagnificationGestureishlatiladi β tuzilma bir xil..scaleEffect(1 + currentAmount)β1.0= hozirgi o'lcham (100%).currentAmountqo'shilishi o'lchamni oshiradi yoki kamaytiradi.value - 1βMagnificationGestureqiymati1.0dan boshlanadi (o'zgarish yo'q). Biz0dan boshlashni xohlayganmiz, shuning uchun1ayiramiz.
Eslatma: Simulator-da ikki barmog'ini ko'rsatish uchun
Optiontugmasini bosib ushlab turing, so'ngra bosing va torting.
Muammo: gesture qayta boshlanishi
Birinchi gesture-dan so'ng qo'l ko'tarilib, qayta boshlanilsa, element boshlang'ich o'lchamiga qaytib "sakrab" tushadi. Buning sababi β currentAmount har safar 0dan boshlanadi.
Yechim: lastAmount qo'shish
@State private var currentAmount: CGFloat = 0
@State private var lastAmount: CGFloat = 0
var body: some View {
Text("Hello, World!")
.font(.title)
.padding(40)
.background(Color.red)
.cornerRadius(10)
.scaleEffect(1 + currentAmount + lastAmount)
.gesture(
MagnificationGesture()
.onChanged { value in
currentAmount = value - 1
}
.onEnded { value in
lastAmount += currentAmount
currentAmount = 0
}
)
}
lastAmountβ oldingi gesture tugaganidagi umumiy o'zgarishni saqlaydionEndedβ gesture tugatilganda:lastAmountgacurrentAmountqo'shiladi,currentAmountesa0ga qaytadiscaleEffect(1 + currentAmount + lastAmount)β joriy va avvalgi o'zgarishlar birgalikda hisoblanadi
Endi gesture qayta boshlanganida, element oxirgi o'lchamidan davom etadi β "sakrab" qaytmaydi.
Amaliy misol: Instagram uslubida rasm zoom
Endi bu gesture-ni haqiqiy ilovaga o'xshash kontekstda ko'ramiz: Instagram-da rasm ustida ikki barmog'ingizni qo'yib kattalashtirish, qo'l ko'tarilganda esa orqaga qaytish.
@State private var currentAmount: CGFloat = 0
var body: some View {
VStack(spacing: 10) {
// Profil qatori (header)
HStack {
Circle()
.frame(width: 35, height: 35)
Text("swiftful_thinking")
Spacer()
Image(systemName: "ellipsis")
}
.padding(.horizontal)
// Rasm (hozircha to'rtburchak)
Rectangle()
.frame(height: 300)
.scaleEffect(1 + currentAmount)
.gesture(
MagnificationGesture()
.onChanged { value in
currentAmount = value - 1
}
.onEnded { value in
withAnimation(.spring()) {
currentAmount = 0
}
}
)
// Like va kommentariya qatori
HStack {
Image(systemName: "heart.fill")
Image(systemName: "text.bubble.fill")
Spacer()
}
.font(.headline)
.padding(.horizontal)
// Caption
Text("This is the caption for my photo πΈ")
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
}
}
Oddiy misoldagi lastAmountdan farq
Bu Instagram misolida onEnded-da currentAmount = 0 ga qaytariladi β ya'ni qo'l ko'tarilganda element o'z asl o'lchamiga qaytadi. Aynan Instagram-dagi xulq: zoom qilasiz, qo'l ko'tarasiz β rasm orqaga qaytadi.
withAnimation(.spring()) qo'shilishi tufayli qaytish silliq va tabiiy ko'rinadi.
onChanged vs onEnded β ikkala misol solishtirma
| Oddiy misol | Instagram misoli | |
|---|---|---|
onChanged | currentAmount = value - 1 | currentAmount = value - 1 |
onEnded | lastAmount += currentAmount; currentAmount = 0 | withAnimation { currentAmount = 0 } |
| Natija | O'lcham saqlanadi | O'lcham orqaga qaytadi |
Gesture-larning umumiy tuzilmasi
Keyingi videolardagi gesture-lar ham xuddi shu tuzilmaga ega β faqat gesture turi o'zgaradi:
.gesture(
MagnificationGesture() // β shu qator o'zgaradi
.onChanged { value in
// joriy holat
}
.onEnded { value in
// tugash holati
}
)
Bu pattern-ni yaxshi o'zlashtirib olish β keyingi gesture-larni o'rganishni ancha osonlashtiradi.