Published on

SwiftUI-da View-ga Padding (ichki bo'sh joy) qo'shish

Authors

Hammaga xush kelibsiz qaytib! Biz ushbu Bootcamp bo'ylab juda yaxshi sur'atda ilgarilab ketmoqdamiz, umid qilamanki, siz ham men kabi bu videolarni yaratishdan zavqlanib turgansiz. Ushbu videoda esa padding haqida gaplashamiz.

Bu, aslida, nomidan ham ko'rinib turibdi: padding — bu, oddiy qilib aytganda, har bir obyekt atrofidagi kichik bo'sh joy. Ammo SwiftUI-da bu juda muhim, chunki padding orqali biz obyektlarni bir-biridan uzoqlashtirishimiz, shuningdek ularni ekran chetlaridan ichkariga suriб qo'yishimiz mumkin — masalan, kichik bir chetlanish (margin) hosil qilish uchun.

Ushbu videoda sizlarga SwiftUI-da obyektga padding qanday qo'shilishini ko'rsataman. Biz obyektning to'rt tomoniga ham, yoki faqat bitta tomoniga — yuqori, past, chap yoki o'ng qismiga — padding qo'shishimiz mumkin. Haqiqatan ham piksel darajasida mukammal ekranlar yaratish uchun, sizlarga padding-ni padding ustiga qatlab qo'yish usulini ham tezda ko'rsatib o'taman, toki aynan o'zimiz xohlagan natijaga erishaylik.


Yangi SwiftUI fayl yaratish

Xcode loyihamizga qaytamiz. Navigator-da o'ng tugmani bosib, ushbu video uchun yangi fayl yaratamiz — bu, har doimgidek, SwiftUI View bo'ladi. Faylga PaddingAndSpacerBootcamp deb nom beramiz. Create tugmasini bosib, canvas-ga kirganimizdan so'ng, hammasi to'g'ri ulanganligiga ishonch hosil qilish uchun Resume tugmasini bosamiz. Endi kod yozishni boshlaymiz.


Matnga fon (background) qo'shish

Avval matnimizga fon rang qo'shaylik:

Text("Hello, world!")
    .background(Color.blue)

Hozirgacha ushbu kursda, agar fon rang matndan kattaroq bo'lishini xohlasak, biz .frame modifikatorini qo'shgan bo'lardik — masalan, eni va balandligi 100 bo'lgan frame:

Text("Hello, world!")
    .background(Color.blue)
    .frame(width: 100, height: 100)

Bu yaxshi ko'rinadi, ammo amalda biz kodimizda 100 kabi qiymatlarni qattiq kodlashdan (hard-coding) qochishga harakat qilishimiz kerak. Nega? Chunki agar "Hello, world!" matni o'lchami o'zgarib, masalan "Hello world, this is fun" bo'lib qolsa, frame baribir 100x100 o'lchamida qotib qoladi — bu esa dinamik emas. Agar bizga aynan 100x100 o'lcham kerak bo'lsa, bu yaxshi, ammo agar matnimiz o'sib-kichrayganida frame ham shunga mos ravishda o'zgarishini xohlasak, biz eni va balandlikni har safar qo'lda o'zgartirib turishimiz kerak bo'lardi.


.padding() — dinamik yechim

Buning o'rniga, frame belgilash o'rniga, matn atrofiga padding qo'shishimiz mumkin. Frame-ni o'chiramiz — endi matnimiz odatdagi ko'rinishiga qaytdi:

Text("Hello, world!")
    .background(Color.blue)

Endi .padding() deb yozamiz:

Text("Hello, world!")
    .background(Color.blue)
    .padding()

Endi padding matnning to'rt tomoniga ham qo'shimcha bo'sh joy qo'shadi. Diqqat qiling: oldindan ko'rishda (preview) matnni o'zgartirsangiz, padding avtomatik tarzda yangilanadi, chunki u dinamik.

Padding qayerga qo'shilishini aniqroq ko'rish

Padding aniq qayerda joylashganini yaxshiroq ko'rsatish uchun, padding-dan oldin ham bir fon rang qo'shamiz:

Text("Hello, world!")
    .background(Color.yellow)
    .padding()
    .background(Color.blue)

Demak, sariq (yellow) rang — bu matnning o'zi, ko'k (blue) rang esa — matn plus padding. .padding() standart holatda barcha to'rt tomonga qo'llaniladi, va u taxminan 10 birlik miqdorida standart bo'sh joy qo'shadi.


To'liq yozilishi: .padding(.all, 10)

.padding()ni shunchaki to'g'ridan-to'g'ri chaqirish, aslida quyidagi bilan bir xil:

Text("Hello, world!")
    .background(Color.yellow)
    .padding(.all, 10)
    .background(Color.blue)

Bu yerda biz edges (tomonlar) parametrini .all (barchasi) deb, va miqdorini 10 deb belgilaymiz. Bu — .padding()ni shunchaki yozishning qisqartirilgan shakli; yuqoridagisi esa to'liq yozilishi. To'liq yozilishida endi biz padding miqdorini o'zgartirishimiz mumkin — masalan, 50 qilib:

.padding(.all, 50)

Keling, buni yana 10ga qaytaramiz.


Padding qaysi tomonlarga qo'llanishini tanlash

Biz padding qaysi tomon(lar)ga qo'llanishini ham o'zgartirishimiz mumkin. Standart holat — .all (barcha to'rt tomon), ammo biz quyidagilardan ham foydalanishimiz mumkin:

  • .vertical — faqat yuqori va past tomon
  • .horizontal — faqat chap va o'ng tomon
  • .top, .bottom, .leading, .trailing — har qaysi tomonning o'ziga alohida
Text("Hello, world!")
    .padding(.leading, 20)

Padding-ni qatlab ishlatish

Padding-ning eng qiziq jihatlaridan biri shunda: biz uni qatlab ishlatishimiz mumkin. Masalan, agar barcha to'rt tomonga 10 padding qoldirib, chap tomonga qo'shimcha padding qo'shmoqchi bo'lsak, yana bir .padding qatorini qo'shishimiz mumkin:

Text("Hello, world!")
    .background(Color.yellow)
    .padding()
    .padding(.leading, 20)
    .background(Color.blue)

Demak, biz barcha to'rt tomonga 10 padding qo'shdik, so'ngra chap tomonga yana qo'shimcha 20 qo'shdik — natijada chap tomondagi umumiy padding endi 30 ga teng bo'ladi. Bu — view-larimizda aniq frame-larni qattiq kodlashdan qochishning yanada dinamikroq usuli: agar kontent o'zgarsa, padding-imiz ham shunga mos ravishda o'zgaradi.


Haqiqiy hayotdagi misol 1: sarlavhani chapga surish

Endi sizlarga padding qanday foyda berishi haqida ikkita tezkor, haqiqiy hayotga oid misol ko'rsataman. Avval barcha modifikatorlarni o'chirib tashlaymiz.

Tasavvur qiling, "Hello, world!" — bizning ilovamizning sarlavhasi. Uni katta sarlavha shrifti va yarim-qalin (semi-bold) qilamiz:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)

Endi, aytaylik, biz uni ekranning chap tomoniga surishni xohlaymiz. Buning uchun, oldin ham qilganimizdek, .frame qo'shamiz — maxWidthni .infinity qilib belgilaymiz:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .frame(maxWidth: .infinity)

Frame-ni ko'rish uchun unga fon rang qo'shamiz:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .frame(maxWidth: .infinity)
    .background(Color.red)

Endi matnni chap tomonga surishni xohlaymiz, shuning uchun frame-ga alignment: .leading qo'shamiz:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .frame(maxWidth: .infinity, alignment: .leading)
    .background(Color.red)

Bu yaxshi ko'rinadi, ammo, albatta, bizning matnimiz telefon ekranining eng chap chetiga yopishib qolgan. Agar siz deyarli har qanday ilovadan foydalangan bo'lsangiz, matn odatda sarlavha boshlanishidan oldin biroz ichkarida, kichik bir margin (chetlanish) bilan boshlanadi. Buni qanday qo'shamiz? Chap qirraga (leading edge) padding qo'shish orqali. Fon belgisidan keyin .padding(.leading, 20) ni qo'shamiz:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .frame(maxWidth: .infinity, alignment: .leading)
    .background(Color.red)
    .padding(.leading, 20)

Endi chap tomonga shu padding qo'shildi. Albatta, fon rangini izohga olib qo'yishimiz mumkin, toki bu haqiqiy ilovada qanday ko'rinishini ko'rsak:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .frame(maxWidth: .infinity, alignment: .leading)
    // .background(Color.red)
    .padding(.leading, 20)

Haqiqiy hayotdagi misol 2: sarlavha + tasvir, va "karta" dizayni

Endi sizlarga yana bir misol ko'rsataman. Frame, padding va fonni o'chirib, faqat ekran markazidagi matnimizni qoldiramiz:

Text("Hello, world!")

Matnni VStack ichiga olish

Endi shu matnni VStack ichiga joylaymiz. Command tugmasini bosib turib matnga bossak, "Embed in VStack" variantini tanlashimiz mumkin (albatta, VStackni qo'lda ham yozish mumkin edi, ammo bu yorliq biroz qulayroq):

VStack {
    Text("Hello, world!")
}

Endi shu matn ostiga yana bir matn qo'shamiz — bu ekranning tasviri (description) bo'ladi:

VStack {
    Text("Hello, world!")
    Text("This is the description of what we will do on this screen. It is multiple lines.")
}

Ko'p qatorli matn tekislashi

Matnimizni chap tomonga (leading) tekislaymiz:

Text("This is the description of what we will do on this screen. It is multiple lines.")
    .multilineTextAlignment(.leading)

Standart holatda, ko'p qatorli matnning tekislanishi (multilineTextAlignment) allaqachon **.leading**ga teng — aynan shu sababdan matn ichidagi bu uch qator allaqachon chap tomonga tekislangan. Agar ilovamizni markazga tekislashni xohlasak, buni .center qilib o'zgartirishimiz mumkin edi, ammo biz buni .leading holida qoldiramiz. Va bu standart qiymat bo'lgani uchun, aslida bu qatorni alohida yozishimiz shart emas.

VStackning o'zini chapga tekislash

Endi ikkita matn komponentimiz ham bor, va biz ularning ikkalasini ham chap tomonga tekislashni xohlaymiz. Buning uchun VStackning tekislanishidan foydalanamiz — alignment: .leadingni qo'shamiz, va bu ikkalasini ham chapga suradi:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}

Butun VStackga fon va padding qo'shish

Endi shu butun VStackga fon rang qo'shamiz:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}
.background(Color.red)

Endi matnimiz va shu fonning chetlari orasida biroz bo'sh joy bo'lishini xohlaymiz. VStackning frame-ini o'zgartirish o'rniga, biz shunchaki padding qo'shamiz. Fon qo'shilishidan oldin, .padding() qo'shamiz — bu standart holatda barcha to'rt tomonga 10 birlik qo'shadi:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}
.padding()
.background(Color.red)

Endi frame yangilandi — matn chetlari atrofida padding paydo bo'ldi. Buni yanada aniqroq ko'rsatish uchun, padding qo'shilishidan oldin ham bir fon rang qo'shamiz:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}
.background(Color.blue)
.padding()
.background(Color.red)

Endi matn obyektimiz ko'k fon bilan markazda, atrofida esa to'rt tomonga padding bor ekanligini ko'rishimiz mumkin. Bu yaxshiroq ko'rinmoqda, ammo men bu qizil fonning ekran chetlariga juda yaqin bo'lishini xohlamayman — telefon ramkasi va shu qizil fon orasida biroz bo'sh joy bo'lishini xohlayman.

Qo'shimcha gorizontal padding

Shuning uchun, fon qo'shilganidan keyin, yana bir .padding qo'shamiz — bu safar tomonlarni .horizontal qilib belgilaymiz, ya'ni faqat chap va o'ng tomon, va miqdorini 10 qilamiz:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}
.background(Color.blue)
.padding()
.background(Color.red)
.padding(.horizontal, 10)

Agar shu yerga yana bir fon rang (masalan, yashil) qo'shsak, bu qo'shimcha 10 padding faqat chap va o'ng tomonda ekanligini ko'rishimiz mumkin, chunki biz .horizontalni belgilagan edik:

.padding(.horizontal, 10)
.background(Color.green)

Yakuniy dizaynni chiroyli qilish

Hozircha bu unchalik chiroyli ko'rinmayapti, ammo keling buni chinakam yaxshi ko'rinishga keltiramiz. Avval yashil va ko'k fonlarni olib tashlaymiz, faqat qizil fonni qoldiramiz, va so'ngra qizil rangni oqga o'zgartiramiz. Buni o'qish osonroq bo'lishi uchun, .backgroundni bir nechta qatorga yozib qo'yamiz:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}
.padding()
.background(
    Color.white
)
.padding(.horizontal, 10)

Soya (shadow) qo'shish

Ammo endi oq fonni oq fon ustida deyarli ko'ra olmaymiz. Shuning uchun, uning orqasiga biroz soya qo'shamiz — color, radius, x va y parametrlari bilan, har birini alohida qatorga yozamiz, o'qish osonroq bo'lishi uchun:

.background(
    Color.white
)
.shadow(
    color: Color.black,
    radius: 10,
    x: 0,
    y: 0
)
.padding(.horizontal, 10)

Rangni qora (black)dan o'zgartiramiz, chunki bu juda qorong'i ko'rinadi. Buning o'rniga, Color.black.opacity(...) — bu rangning shaffofligini (opacity) o'zgartirish usuli — yordamida, soyani 30% shaffoflikka, ya'ni och kulrang (light gray) rangga o'zgartiramiz:

.shadow(
    color: Color.black.opacity(0.3),
    radius: 10,
    x: 0,
    y: 0
)

Bu biroz yaxshiroq ko'rinadi. Endi soyani biroz pastga suramiz — xni 0 holida qoldiramiz, yni esa 10ga o'zgartiramiz:

.shadow(
    color: Color.black.opacity(0.3),
    radius: 10,
    x: 0,
    y: 10
)

Endi bu, go'yo soya bizning obyektimizning pastida turganday ko'rinadi.

Burchaklarni yumaloqlash (corner radius)

Albatta, ilovamizda keskin burchaklarni yoqtirmaymiz, shuning uchun soyadan oldin cornerRadius qo'shamiz — 10 qilib belgilaymiz:

.background(
    Color.white
)
.cornerRadius(10)
.shadow(
    color: Color.black.opacity(0.3),
    radius: 10,
    x: 0,
    y: 10
)
.padding(.horizontal, 10)

Bu allaqachon ilovada uchraydigan biror narsaga o'xshab qoldi.

Qo'shimcha vertikal padding

Endi yana biroz padding qo'shamiz — yuqori va past tomonlarga qo'shimcha bo'sh joy berishni xohlayman. Shuning uchun, fon qatlamidan oldin, yana bir .padding(.vertical, 30) qo'shamiz:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
}
.padding()
.padding(.vertical, 30)
.background(
    Color.white
)
.cornerRadius(10)
.shadow(
    color: Color.black.opacity(0.3),
    radius: 10,
    x: 0,
    y: 10
)
.padding(.horizontal, 10)

Ikki matn orasiga padding qo'shish

Va nihoyat, bu ikki obyekt orasiga ham biroz bo'sh joy qo'shmoqchiman. Buning uchun, "Hello, world!" matnining pastiga, .padding(.bottom, 20) qo'shamiz:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .padding(.bottom, 20)

Endi bu, haqiqiy ilovada qanday foydali bo'lishi mumkinligini ko'rishimiz mumkin. Buni 10ga o'zgartiraman, chunki menimcha bu biroz yaxshiroq ko'rinadi:

Text("Hello, world!")
    .font(.largeTitle)
    .fontWeight(.semibold)
    .padding(.bottom, 10)

Yakuniy kod

Yakunda, bizning to'liq kodimiz quyidagicha ko'rinadi:

VStack(alignment: .leading) {
    Text("Hello, world!")
        .font(.largeTitle)
        .fontWeight(.semibold)
        .padding(.bottom, 10)

    Text("This is the description of what we will do on this screen. It is multiple lines.")
        .multilineTextAlignment(.leading)
}
.padding()
.padding(.vertical, 30)
.background(
    Color.white
)
.cornerRadius(10)
.shadow(
    color: Color.black.opacity(0.3),
    radius: 10,
    x: 0,
    y: 10
)
.padding(.horizontal, 10)

Xulosa

Mana, padding bo'yicha shu qadar. Endi sizlarda padding nima uchun shunchalik muhim ekanligi haqida haqiqiy misollar bor — asosan, chunki u dinamik, va padding-dan foydalanib, biz ilovamizda aniq frame-larni qattiq kodlashdan qochishimiz mumkin, bu esa juda foydali.

Bilaman, videoning boshida spacerlarni ham ko'rib chiqamiz deb aytgan edim, ammo bu video allaqachon biroz uzun bo'lib ketdi, va spacer-lar ham juda muhim, shuning uchun ularga alohida video bag'ishlashga qaror qildim. Shunday qilib, bu video uchun shu qadar.

Umid qilaman, padding haqidagi ushbu video sizga foydali bo'ldi — u juda foydali vosita. Har doimgidek, men — Nick, bu Swiftful Thinking, keyingi videoda ko'rishamiz!

Buy mea coffee