Published on

SwiftUI-da Spacer-dan qanday foydalanish kerak

Authors

Bilasizmi, hayotda ba'zan narsalar juda ko'p bo'lib ketadi, va sizga bir oz bo'sh joy kerak bo'ladi. Ilova yaratishda ham xuddi shunday — ba'zan ekranga juda ko'p element joylashtirib qo'yamiz, bu ham ko'p bo'lib ketadi, va bizga biroz bo'sh joy qo'shish kerak bo'ladi. Xo'sh, nima qilamiz? SwiftUI-da biz spacer qo'shamiz.

Hammaga salom! Men — Nick, va ushbu videoda spacerlar haqida gaplashamiz. Spacer — SwiftUI-da juda qulay komponent. Biz ikki obyekt orasiga spacer qo'shib, ular orasiga aynan bo'sh joy qo'shishimiz va shu obyektlarni bir-biridan uzoqlashtirishimiz mumkin.

Spacer-lar juda aqlli va moslashuvchan: ulardan gorizontal yoki vertikal yo'nalishda foydalanishimiz mumkin, va bitta stack ichida bir nechta spacer qo'shib, elementlar orasida teng oraliq hosil qilishimiz mumkin. Shuning uchun spacer-lar SwiftUI-da juda foydali va qulay — biz ulardan layout va format yaratishda doimiy foydalanamiz, chunki spacer yordamida obyektlarni yuqoriga, pastga, chapga yoki o'ngga surib qo'yishimiz mumkin. Va ularning qanday ishlashini bir tushunib olgach, ularni qo'llash juda-juda oson.

Keling, ko'rib chiqaylik.


Yangi SwiftUI fayl yaratish

Xcode loyihamizga yana bir bor qaytdik. Ushbu video uchun yangi fayl yaratamiz — Navigator-da o'ng tugmani bosib, yangi fayl yaratamiz. Bu, har doimgidek, SwiftUI View bo'ladi, va bu safar spacer-lar haqida bo'ladi, shuning uchun unga SpacerBootcamp deb nom beramiz. Create tugmasini bosamiz, va fayl yaratilgandan so'ng, canvas-da Resume tugmasini bosib, hammasi to'g'ri ulanganligiga ishonch hosil qilamiz. Endi kod yozishni boshlaymiz.

Agar siz ushbu kursni kuzatib borayotgan bo'lsangiz, biz allaqachon stacklar haqida video qilgan edik, va u yerda HStack va VStacklarni o'rgangan edik — ularni ushbu videoda ham ishlatamiz.


Ikki to'rtburchak va ular orasidagi standart oraliq

Avval HStack (gorizontal stack) qo'shamiz, va uning ichiga ikkita to'rtburchak (rectangle) joylashtiramiz:

HStack {
    Rectangle()
        .frame(width: 100, height: 100)

    Rectangle()
        .frame(width: 100, height: 100)
}

Endi buni aniqroq ko'rish uchun, shu HStack-ga fon rang qo'shamiz, va ikkinchi to'rtburchakning rangini farqlash uchun o'zgartiramiz:

HStack {
    Rectangle()
        .frame(width: 100, height: 100)

    Rectangle()
        .fill(Color.red)
        .frame(width: 100, height: 100)
}
.background(Color.blue)

Endi bizda qora to'rtburchak, qizil to'rtburchak, va ular orasida bir oz bo'sh joy mavjud. Esingizda bo'lsin, bu oraliq — HStack ichidagi har bir obyekt orasidagi standart padding, ya'ni spacing parametri nil (standart) qoldirilganda paydo bo'ladigan, taxminan 8 birlikli bo'sh joy.

Albatta, biz shu standart oraliqni o'zgartirishimiz mumkin — istalgan raqamni qo'yib, masalan 50:

HStack(spacing: 50) {
    Rectangle()
        .frame(width: 100, height: 100)

    Rectangle()
        .fill(Color.red)
        .frame(width: 100, height: 100)
}
.background(Color.blue)

Bu ikki obyekt orasidagi oraliqni oshiradi.


Obyektlarni chetlarga surish uchun Spacer qo'shish

Endi, agar biz obyektlarimizni ekranning eng chetlariga suriб qo'yishni xohlasak-chi? Buning oraliq miqdorini taxminiy hisoblab topishga harakat qilishimiz mumkin edi — masalan, 200 deb qo'yib ko'rishimiz mumkin edi, ammo bu mukammal emas, aniq emas, va biz buni qilishni yoqtirmaymiz.

Shuning uchun, buning o'rniga, biz shu to'rtburchaklar orasiga yana bir obyekt sifatida spacer qo'shamiz:

HStack {
    Rectangle()
        .frame(width: 100, height: 100)

    Spacer()

    Rectangle()
        .fill(Color.red)
        .frame(width: 100, height: 100)
}
.background(Color.blue)

Spacer — shunchaki frame ichida imkon qadar katta bo'lishga harakat qiladi. Endi shu spacer ikki obyektni chap va o'ng tomonga suриб qo'ymoqda.

Standart holatda spacer shaffof (transparent) — biz uni ko'ra olmaymiz. Ammo sizlarga spacer aynan qayerda joylashganini ko'rsatish uchun, unga balandligi 10 bo'lgan frame va orange fon rang beramiz:

Spacer()
    .frame(height: 10)
    .background(Color.orange)

Endi spacer aslida markazda ekanligini, va obyektlarni chap va o'ngga suриб qo'yayotganini ko'rishimiz mumkin.

Spacer avtomatik o'lcham o'zgartiradi

Eng qiziq joyi — spacer avtomatik ravishda o'lchamini o'zgartiradi. Agar to'rtburchaklardan birini, masalan qizil to'rtburchakni, 200 ga kattalashtirsak:

Rectangle()
    .fill(Color.red)
    .frame(width: 200, height: 200)

Spacer o'lchamini qayta hisoblab, ikkala obyektni ham, imkoni boricha, chap va o'ngga suriб turadi — faqat endi u oldingisidan biroz kichikroq. Keling, buni yana 100ga qaytaramiz.

Spacer-ni chap tomonga ko'chirish

Endi spacer-ni chap tomonga ko'chiraylik — uni qirqib olib, qora to'rtburchakdan oldin, HStack-ning boshiga joylashtiramiz:

HStack {
    Spacer()
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .frame(width: 100, height: 100)

    Rectangle()
        .fill(Color.red)
        .frame(width: 100, height: 100)
}
.background(Color.blue)

Endi spacer chap tomonda, va ikkala obyektni ham o'ng tomonga surib qo'ymoqda. Bu juda foydali, chunki agar bizda obyektlarni ekranning eng o'ng, eng chap, eng yuqori yoki eng past qismiga surishni xohlaydigan biror view bo'lsa, buni spacer orqali amalga oshirishimiz mumkin.


Bir nechta spacer — teng oraliqlar

Yana bir juda foydali jihat: agar bir xil stack ichida bir nechta spacer bo'lsa, barcha spacer-lar avtomatik ravishda bir xil o'lchamga ega bo'ladi. Bu nimani anglatadi, ko'rib chiqaylik.

Avval spacingni 0ga o'zgartiramiz, shunda stack ichida faqat spacer va ikkita obyektimiz qoladi. To'rtburchaklarimizni biroz kichraytiramiz — 50x50 qilamiz, va pastga yana bir to'rtburchak qo'shamiz — uni yashil qilamiz:

HStack(spacing: 0) {
    Spacer()
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .frame(width: 50, height: 50)

    Rectangle()
        .fill(Color.red)
        .frame(width: 50, height: 50)

    Rectangle()
        .fill(Color.green)
        .frame(width: 50, height: 50)
}
// .background(Color.blue)

Hozircha bizda bitta spacer bor, va uning o'lchamini sariq chiziq orqali ko'rishimiz mumkin (odatda haqiqiy ilovalarda spacer-ga frame va fon rang qo'shmaysiz — men buni shunchaki ko'rsatish uchun qilyapman). Ko'k fon rangini izohga olib qo'yamiz, chunki bizga hozir kerak emas.

Endi, agar shu HStack ichida ikkita spacer bo'lsa-chi? Eng pastdagi spacer-ni nusxalab, yashil to'rtburchakdan keyin, eng o'ng tomonga joylashtiramiz:

HStack(spacing: 0) {
    Spacer()
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .frame(width: 50, height: 50)

    Rectangle()
        .fill(Color.red)
        .frame(width: 50, height: 50)

    Rectangle()
        .fill(Color.green)
        .frame(width: 50, height: 50)

    Spacer()
        .frame(height: 10)
        .background(Color.orange)
}

Endi oldindan ko'rishda ikkita spacer borligini ko'ramiz, va ular aynan bir xil o'lchamda — bu juda foydali, chunki endi biz uchta obyektimizni markazga tekislashimiz mumkin.

Yana bir spacer-ni nusxalab, ikkita to'rtburchak orasiga, va yana bittasini qizil va yashil to'rtburchaklar orasiga joylashtiramiz:

HStack(spacing: 0) {
    Spacer()
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .frame(width: 50, height: 50)

    Spacer()
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .fill(Color.red)
        .frame(width: 50, height: 50)

    Spacer()
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .fill(Color.green)
        .frame(width: 50, height: 50)

    Spacer()
        .frame(height: 10)
        .background(Color.orange)
}

Demak, tartibimiz endi: spacer, to'rtburchak, spacer, to'rtburchak, spacer, to'rtburchak, spacer. Va ko'rib turganingizdek, bu spacer-larning barchasi avtomatik ravishda bir xil o'lchamga moslashdi — bu bizga layout yaratishda juda yordam beradi.

Agar shu spacer-lar shaffof bo'lsa (fon rangni izohga olamiz), buni ilovada qanday qo'llanilishini tasavvur qilish mumkin — masalan, agar sizda uch xil tugma bo'lsa va ularni ekran bo'ylab teng masofada tarqatib qo'yishni xohlasangiz. Keling, oranj fon ranglarini izohdan chiqarib, qaytarib qo'yamiz, toki ular ekranda yana ko'rinsin.


Spacer-ning standart minimal uzunligi (minimum length)

Endi spacer haqida yana bir muhim narsani ta'kidlab o'tmoqchiman: spacer-ning standart minimal uzunligi mavjud. Spacer( deb yozganimizda, qavs ichida ikkita variant taklif qilinadi: oddiy standart (Spacer()) va minLength parametri bilan birga keladigan variant.

Standart holatda, ya'ni biz shunchaki Spacer() deb yozganimizda, minLength qiymati standart (default) holatda qoladi — bu, menimcha, taxminan 8 yoki 10 ga teng. Demak, minLength: nil deb yozish, oddiy Spacer() deb yozish bilan bir xil:

Spacer(minLength: nil)

Bu, asosan, shuni bildiradi: agar HStack qaysidir sababga ko'ra juda siqilib qolsa ham, bu spacer baribir kamida taxminan 10 birlikli minimal uzunlikka ega bo'ladi.

Misol: HStack-ni siqib ko'rish

Buni sizlarga ko'rsatish uchun, HStack-ning pastiga biroz padding qo'shamiz. Oldingi videoda padding haqida gaplashgan edik, shuning uchun bu nima ekanligini bilasiz — bu, asosan, view tashqarisiga bo'sh joy qo'shadi:

.padding(.horizontal, 200)

Bu biroz g'ayritabiiy raqam, ammo men sizlarga shuni ko'rsatmoqchiman: bu obyekt markazga siqilganda, spacer-lar imkon qadar ko'p qisqaradi, ammo ularning standart minimal uzunligi (taxminan 8 yoki 10) bo'lgani uchun, ulardan butunlay kichrayib yo'qolib ketmaydi.

HStack-ga ham fon rang qaytarib qo'yamiz — Color.yellow, va ko'k rangni ham qaytaramiz:

HStack(spacing: 0) {
    Spacer(minLength: nil)
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .frame(width: 50, height: 50)

    Spacer(minLength: nil)
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .fill(Color.red)
        .frame(width: 50, height: 50)

    Spacer(minLength: nil)
        .frame(height: 10)
        .background(Color.orange)

    Rectangle()
        .fill(Color.green)
        .frame(width: 50, height: 50)

    Spacer(minLength: nil)
        .frame(height: 10)
        .background(Color.orange)
}
.background(Color.yellow)
.padding(.horizontal, 200)
.background(Color.blue)

Endi bizda ko'k rang — bu padding joylashgan joy, sariq rang — bu HStack-ning o'zi. Standart holatda, bu spacer-larning barchasi shu minimal uzunlikka ega, va aynan shuning uchun, hatto obyektlar bir-biriga siqilib turganda ham, biz spacer-lar uchun kichik oranj chiziqlarni hamon ko'rib turamiz.

minimumLengthni nolga tushirish

Ammo, ilovangizda ko'pincha shunday holat bo'ladi: obyektlar bir-biriga siqilib turganda, sizga ortiqcha oraliq kerak emas — siz obyektlarning kattaroq bo'lib qolishini, ular orasida shu oraliq bo'lmasligini xohlaysiz. Bunday holatda, minLengthni **0**ga o'rnatishingiz mumkin:

Spacer(minLength: 0)

Buni qilganimizda, chap tomondagi spacer butunlay yo'qolib ketadi. Bu, asosan, agar chegaralar shu darajada siqilib qolgan bo'lsa, spacer-ga nolga tushishga ruxsat beradi. Eng oxirgi spacer-ga ham xuddi shunday qilamiz — minLength: 0:

Spacer(minLength: 0)

Endi ko'rib turishimiz mumkin: chetdagi spacer-lar, ular siqilganida, butunlay yo'qolib qolgan — chunki ularda minimal uzunlik mavjud emas.

Va agar biz padding-ni izohga olib, oldingi oddiy holatga qaytarsak, bu spacer-lar qayta paydo bo'ladi — bu aynan biz xohlagan natija.

Spacer-larning minimal uzunligi bor ekanligini bilish muhim, chunki ko'p hollarda odamlar spacer qo'shadi, ammo nega ular hatto eng siqilgan holatda ham bir oz joy egallab turishini tushunmaydi. Bu — sizlarni kelajakda biroz debuggingdan qutqaradigan kichik maslahat bo'ldi.


Real misol: ekran yuqorisidagi tugmalar

Videoni yakunlashdan oldin, ilovada spacer-ni qachon ishlatishimga doir bitta tezkor misol ko'rsatmoqchiman.

HStack ichidagi barcha kodni o'chirib, ikkita rasm (image) qo'shamiz:

HStack {
    Image(systemName: "xmark")
    Image(systemName: "gear")
}

Bularning ikkalasini ham bir oz kattalashtirmoqchiman, shuning uchun .font(.title) qo'shamiz:

HStack {
    Image(systemName: "xmark")
    Image(systemName: "gear")
}
.font(.title)

Tezkor maslahat: agar HStack ichida ishlayotgan bo'lsak, va HStack ichidagi barcha obyektlar bir xil shriftga ega bo'lishini xohlasak, biz shu shriftni HStack-ning o'ziga qo'yishimiz mumkin — shunda buni faqat bir marta yozish kifoya, va ikkala obyekt ham shu shriftga ega bo'ladi. Bu xuddi shu tarzda ranglar uchun ham ishlaydi.

Endi ikkala rasmimiz ham bir oz kattaroq ko'rinmoqda. Men bularni view-ning yuqori chap va yuqori o'ng tomoniga surishni xohlayman, chunki odatda bunday tugmalar aynan shu joyda bo'ladi.

Ikki tomonga tarqatish

Avval ularni chap va o'ngga tarqatishni xohlayman — buning uchun ular orasiga spacer qo'shamiz:

HStack {
    Image(systemName: "xmark")
    Spacer()
    Image(systemName: "gear")
}
.font(.title)

Endi ular biroz juda o'ng tomonga yaqin bo'lib qolgan, shuning uchun chetlarga padding qo'shmoqchiman. HStack-ga, oldin qilganimizdek, padding qo'shamiz — .horizontal, va aniq raqam yozmasdan, shunchaki standart miqdorni qoldiramiz:

HStack {
    Image(systemName: "xmark")
    Spacer()
    Image(systemName: "gear")
}
.font(.title)
.padding(.horizontal)

Hammasini ekranning yuqorisiga surish

Endi men buni butun ekranning eng yuqorisiga surishni xohlayman. Buning uchun, shu HStack-ni VStack ichiga joylashtiramiz — Command tugmasini bosib turib HStack-ga bosamiz va "Embed in VStack" variantini tanlaymiz:

VStack {
    HStack {
        Image(systemName: "xmark")
        Spacer()
        Image(systemName: "gear")
    }
    .font(.title)
    .padding(.horizontal)
}

Endi barcha obyektlarni yuqoriga surish uchun, shu HStack-dan keyin yana bir spacer qo'shamiz — esingizda bo'lsin, spacer imkon qadar katta bo'lishga harakat qiladi:

VStack {
    HStack {
        Image(systemName: "xmark")
        Spacer()
        Image(systemName: "gear")
    }
    .font(.title)
    .padding(.horizontal)

    Spacer()
}

Endi bizning obyektlarimiz yuqorida joylashgan.

Spacer-larni vizual ko'rsatish

Sizlarga shu spacer-larni yana aniqroq ko'rsatish uchun, ularga ham frame va fon rang qo'shamiz. Birinchisiga — balandligi 10 bo'lgan frame va orange fon, ikkinchisiga esa — eni 10 bo'lgan frame va orange fon (chunki bu safar u vertikal yo'nalishda harakatlanadi):

HStack {
    Image(systemName: "xmark")
    Spacer()
        .frame(height: 10)
        .background(Color.orange)
    Image(systemName: "gear")
}
.font(.title)
.padding(.horizontal)
.background(Color.yellow)
.background(Color.blue)

Spacer()
    .frame(width: 10)
    .background(Color.orange)

Demak, bizda yuqoridagi HStack bor — uning sariq fon rangi, padding-dan tashqarida esa ko'k fon rangi bor. Bu fon ranglarni yashirib qo'yaman, chunki ular unchalik chiroyli ko'rinmaydi, ammo men sizlarga hamma narsa aynan qayerda joylashganini ko'rsatmoqchi edim.

Endi bizda ikkita spacer bor: birinchisi — HStack ichidagi gorizontal spacer, bu xmarkni eng chap tomonga, gearni esa eng o'ng tomonga suriб qo'yadi. Ikkinchisi esa — bu asosiy VStack.

Shu VStack-ga ham fon rang qo'shsak — Color.yellow:

VStack {
    // ...
}
.background(Color.yellow)

Bizda juda katta HStack mavjud bo'ladi. Agar shu pastdagi spacer-ni izohga olib qo'ysam, bizda faqat shu HStack qolardi. Ammo men spacer qo'shdim, toki hamma narsani yuqoriga suriб qo'ysin — shuning uchun bu spacer imkon qadar katta bo'lib kengaydi va obyektlarimizni yuqoriga surib qo'ydi. Bu fon rangni yana izohga olaman.

Spacer pastdagi obyektni ham suradi

Spacer-dan keyin yana bir view qo'shishimiz ham mumkin — masalan, balandligi 55 bo'lgan to'rtburchak:

VStack {
    HStack {
        Image(systemName: "xmark")
        Spacer()
        Image(systemName: "gear")
    }
    .font(.title)
    .padding(.horizontal)

    Spacer()

    Rectangle()
        .frame(height: 55)
}

Shunda spacer o'lchamini qayta hisoblab, to'rtburchakni pastga suriб qo'yganini, yuqoridagi elementlarimiz esa yuqorida qolganini ko'rishimiz mumkin.

Endi spacer-lardagi frame va fon rangni olib tashlasak, sahifamizning qanday birlashayotganini ko'rishimiz mumkin: biz tugmalarimizni yuqoriga qo'yamiz, va ehtimol pastga tab bar kabi biror narsa qo'yishimiz mumkin.


Xulosa

Mana shu — spacer-lar haqida shu qadar. Bu shunchaki spacer-lar haqida tezkor video edi, chunki ulardan ko'plab view-larda foydalaniladi, va ular ekranlaringizni formatlash va tartiblashda yordam beradi.

Har doimgidek, men — Nick, bu Swiftful Thinking, va keyingi videoda ko'rishamiz!

Buy mea coffee