- Published on
SwiftUI-da GeometryReader yordamida view o'lchami va joylashuvini aniqlash
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
GeometryReader β SwiftUI'da view'larning aniq o'lchami va ekrandagi joylashuvini olish uchun ishlatiladigan kuchli vosita. Ammo uni haddan ziyod ko'p joyda ishlatish ilovangizni sekinlashtirishi mumkin β shuning uchun birinchi navbatda uni ishlatmasdan yechim topishga harakat qiling, va faqat haqiqatan ham kerak bo'lganda qo'llang.
UIScreen.main.bounds.width ning cheklovi
Ikki to'rtburchakni HStack ichiga joylashtirib, ulardan biri ekranning 2/3 qismini egallashini xohlaymiz:
HStack(spacing: 0) {
Rectangle()
.fill(Color.red)
.frame(width: UIScreen.main.bounds.width * 0.666)
Rectangle()
.fill(Color.blue)
}
.ignoresSafeArea()
Bu portret rejimda yaxshi ishlaydi β qizil 2/3, ko'k 1/3 ni egallaydi. Ammo qurilmani landscape rejimga o'zgartirganingizda muammo paydo bo'ladi: UIScreen.main.bounds.width qurilmaning fizik enini qaytaradi va qurilma aylanganida yangilanmaydi β shuning uchun qizil to'rtburchak landscape rejimda ham portretdagi pixel kengligini saqlab qoladi.
GeometryReader bilan yechim
GeometryReader esa joriy content maydonining haqiqiy o'lchamini qaytaradi va orientatsiya o'zgarganda avtomatik yangilanadi:
GeometryReader { geometry in
HStack(spacing: 0) {
Rectangle()
.fill(Color.red)
.frame(width: geometry.size.width * 0.666)
Rectangle()
.fill(Color.blue)
}
.ignoresSafeArea()
}
Endi simulyatorda qurilmani aylantirsak, qizil to'rtburchak har doim ekranning aynan 2/3 qismini egallaydi β portret va landscape rejimda ham.
Qachon GeometryReader ishlatmaslik kerak
GeometryReader qimmat vosita: bir ekranda ko'p ishlatilsa, UI biroz sekinlashishi mumkin. Shuning uchun:
- Avval
Spacer,HStack,VStack,frame(maxWidth: .infinity)kabi standart SwiftUI vositalar bilan yechim topishga harakat qiling. - Faqat ulardan biri ham yetarli bo'lmaganda
GeometryReaderqo'llang. - Ayniqsa boshlang'ich dasturchilar uni kerak bo'lmagan joylarda ham ishlatib qo'yishadi β bundan saqlaning.
2-misol: Gorizontal ScrollView ichida 3D aylanish animatsiyasi
Endi qiziqroq misol β gorizontal scroll view ichida har bir element ekranning markazidan qanchalik uzoqda ekaniga qarab 3D burilish (rotation3DEffect) qo'shamiz.
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(0..<20) { index in
GeometryReader { geometry in
RoundedRectangle(cornerRadius: 20)
.rotation3DEffect(
.degrees(getPercentage(geo: geometry) * 40),
axis: (x: 0, y: 1, z: 0)
)
}
.frame(width: 300, height: 250)
.padding()
}
}
}
frame va paddingni GeometryReaderga qo'llamiz, ichidagi RoundedRectanglega emas β chunki GeometryReader elementning aniq o'lchamini bilishi uchun o'lchami uning o'zida belgilanishi kerak.
getPercentage funksiyasi
func getPercentage(geo: GeometryProxy) -> Double {
let maxDistance = UIScreen.main.bounds.width / 2
let currentX = geo.frame(in: .global).midX
return Double(1 - (currentX / maxDistance))
}
maxDistanceβ ekranning yarmi (markazga masofa)geo.frame(in: .global).midXβ shu elementning global koordinatalardagi markaziy x-nuqtasi1 - (currentX / maxDistance)β elementning markazdan qanchalik chetda ekanining foizi
Element ekran markazida bo'lganda currentX β maxDistance, natija β 0 daraja (to'g'ri). Element chetga siljigan sari foiz ortib, burilish kuchayadi (* 40 β maksimal burchak 40 daraja).
To'liq natija
struct GeometryReaderBootcamp: View {
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(0..<20) { index in
GeometryReader { geometry in
RoundedRectangle(cornerRadius: 20)
.rotation3DEffect(
.degrees(getPercentage(geo: geometry) * 40),
axis: (x: 0, y: 1, z: 0)
)
}
.frame(width: 300, height: 250)
.padding()
}
}
}
}
func getPercentage(geo: GeometryProxy) -> Double {
let maxDistance = UIScreen.main.bounds.width / 2
let currentX = geo.frame(in: .global).midX
return Double(1 - (currentX / maxDistance))
}
}
Simulyatorda sinab ko'rsak: kartochkalar aylantirib ko'rilganda, markazdagi element to'g'ri turadi, chetga siljigan elementlar esa go'yo "burilib kelayotgandek" ko'rinadi β bu juda chiroyli effekt, va buning uchun faqat bir necha qator kod yetarli bo'ldi.
Xulosa
GeometryReader bilan xuddi shu mantiqni vertikal ScrollViewda ham ishlatish mumkin β elementlar yuqoridan pastga scroll qilinayotganda ularning opacity yoki scale'ini o'zgartirish, va hokazo. Konsepsiya bir xil: geo.frame(in: .global)dan kerakli koordinatani olib, animatsiya modifikatoriga uzatish.
GeometryReaderni kelajakdagi loyihalarda ko'proq ishlatamiz β shuning uchun asoslarni yaxshi tushuning, ammo uni faqat haqiqatan ham zarur bo'lganda qo'llang.