- Published on
SwiftUI-da Popover modifier — native popover yaratish (iOS 16.4+)
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Bu videoda biz Popover modifier-ni ko'rib chiqamiz. Avvalroq "popover boot camp" videosida sheet va transition yordamida o'zimiz yasagan edik — bu safar esa iOS 16.4 da kelgan native SwiftUI versiyasini ko'ramiz.
Popover — foydalanuvchiga kichik ma'lumot, menyu yoki maslahat ko'rsatishning eng qulay usuli. Sheet va FullScreenCover-dan farqi: butun ekranni qoplamaydi, tugma yonida paydo bo'ladi.
Boshlang'ich sozlama
struct NativePopoverBootcamp: View {
@State private var showPopover: Bool = false
var body: some View {
ZStack {
Color.gray
.ignoresSafeArea()
Button("Bosing") {
showPopover.toggle()
}
.popover(isPresented: $showPopover) {
Text("Salom!")
}
}
}
}
Bu kodni ishlatganda — sheet chiqadi, popover emas! Nima uchun?
presentationCompactAdaptation — popover ko'rinishi uchun shart
iPhone-da popover standart holatda sheet kabi ko'rinadi. Haqiqiy popover ko'rinishi uchun yangi modifier kerak:
Button("Bosing") {
showPopover.toggle()
}
.popover(isPresented: $showPopover) {
Text("Salom!")
// ✅ Bu modifier bo'lmasa sheet ko'rinadi
.presentationCompactAdaptation(.popover)
}
Eslatma: presentationCompactAdaptation — iOS 16.4 dan boshlab mavjud. Loyihangizning minimal iOS versiyasini 16.4 ga o'rnating.
Adaptatsiya turlari
// Standart sheet ko'rinishi
.presentationCompactAdaptation(.sheet)
// To'liq ekran
.presentationCompactAdaptation(.fullScreenCover)
// Haqiqiy popover — tugma yonida paydo bo'ladi
.presentationCompactAdaptation(.popover)
Apple bu modifier orqali kelajakda sheet va fullScreenCover-ni ham shu usulga o'tkazishini ko'rsatyapti. Shuning uchun .popover modifier-ini avvaldan o'rganib qo'ygan ma'qul.
Popover qayerda paydo bo'ladi?
Popover — modifier qo'yilgan view-ning tepasida paydo bo'ladi. Shuning uchun modifier tugmaga qo'yish kerak, katta container-ga emas:
// ❌ NOTO'G'RI — ZStack-ga qo'yilgan, popover ekran burchagida paydo bo'ladi
ZStack {
Color.gray.ignoresSafeArea()
Button("Bosing") { showPopover.toggle() }
}
.popover(isPresented: $showPopover) { ... }
// ✅ TO'G'RI — tugmaga qo'yilgan, popover tugma yonida paydo bo'ladi
ZStack {
Color.gray.ignoresSafeArea()
Button("Bosing") { showPopover.toggle() }
.popover(isPresented: $showPopover) { ... }
}
attachmentAnchor — aniqroq joylashuv sozlash
Button("Bosing") {
showPopover.toggle()
}
.padding()
.background(Color.yellow)
.popover(
isPresented: $showPopover,
attachmentAnchor: .point(.top), // tugmaning qaysi nuqtasidan
arrowEdge: .bottom // macOS uchun, iOS-da ta'sir qilmaydi
) {
Text("Popover mazmuni")
.padding(20)
.presentationCompactAdaptation(.popover)
}
attachmentAnchor turlari:
.point(.center) // tugma markazidan
.point(.top) // tugma yuqorisidan — popover tepada paydo bo'ladi
.point(.bottom) // tugma pastidan — popover pastda paydo bo'ladi
.point(.topLeading) // tugmaning yuqori-chap burchagidan
Apple-ning avtomatik ekran logikasi
Popover joylashuvi avtomatik boshqariladi — ekrandan chiqmaydi:
VStack {
// Tugma ekranning YUQORISIDA bo'lsa
Button("Yuqoridagi tugma") { showPopover.toggle() }
.popover(isPresented: $showPopover) { ... }
// → Popover PASTDA paydo bo'ladi
Spacer()
}
VStack {
Spacer()
// Tugma ekranning PASTIDA bo'lsa
Button("Pastdagi tugma") { showPopover.toggle() }
.popover(isPresented: $showPopover) { ... }
// → Popover YUQORIDA paydo bo'ladi
}
Bu Apple-ning avtomatik UX logikasi — popover hech qachon ekrandan tashqariga chiqmaydi. Siz attachment anchor-ni belgilaysiz, Apple esa eng qulay joyni tanlaydi.
Tashqarini bosish bilan yopish
Sheet-dan farqli ravishda, popover-ni yopish uchun faqat ekranning istalgan joyini bosish yetarli — alohida "Yopish" tugmasi kerak emas:
// Sheet — dismiss uchun kod kerak
@Environment(\.presentationMode) var presentationMode
presentationMode.wrappedValue.dismiss()
// Popover — ekranning istalgan joyini bosish yopadi, kod kerak emas
Haqiqiy dunyo misoli — feedback menyu
struct NativePopoverBootcamp: View {
@State private var showPopover: Bool = false
@State private var feedbackOptions: [String] = [
"Juda yaxshi 😊",
"O'rtacha 🙂",
"Yomon 😡"
]
var body: some View {
VStack {
Spacer()
Button("Fikr bildiring") {
showPopover.toggle()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.popover(isPresented: $showPopover) {
VStack(alignment: .leading, spacing: 12) {
ForEach(feedbackOptions, id: \.self) { option in
Button(option) {
// Fikr tanlandi
showPopover = false
}
// Oxirgi element bundan tashqari divider
if option != feedbackOptions.last {
Divider()
}
}
}
.padding(20)
.presentationCompactAdaptation(.popover)
}
}
}
}
Ko'p variant bo'lsa ScrollView ichiga ham solish mumkin:
.popover(isPresented: $showPopover) {
ScrollView {
VStack(alignment: .leading, spacing: 12) {
ForEach(feedbackOptions, id: \.self) { option in
Button(option) { showPopover = false }
Divider()
}
}
.padding(20)
}
.presentationCompactAdaptation(.popover)
}
Sheet, FullScreenCover va Popover taqqoslash
| Sheet | FullScreenCover | Popover | |
|---|---|---|---|
| Ko'rinish | Pastdan chiqadi | To'liq ekran | Tugma yonida |
| Yopish | Pastga surish | Kod bilan | Istalgan joy |
| Hajmi | Katta | To'liq | Kichik |
| Qachon | Yangi ekran | To'liq o'tish | Kichik info/menyu |
| iOS versiya | Barcha | Barcha | 16.4+ |
Xulosa
Button("Menyu") {
showPopover.toggle()
}
.popover(isPresented: $showPopover) {
// kontent
.presentationCompactAdaptation(.popover) // ← shart!
}
Popover — kichik maslahat, menyu yoki tugmachalar to'plamini ko'rsatish uchun ideal. Sheet-dan ko'ra ancha yengil va foydalanuvchi uchun qulayroq. Ekranning istalgan joyini bosib yopilishi katta UX afzalligi.