SnapKit 2: Asosiy Constraint'lar — edges, center, size, offset va inset
🧩 SnapKit — Zero to Hero
SnapKit 2: Asosiy Constraint'lar — edges, center, size, offset va inset
Holat: Ushbu qo'llanma 2026-yil oktabr holatiga ko'ra SnapKit 5.7+ va Swift 6 talablari asosida tayyorlangan. Barcha kodlar zamonaviy
@MainActorva xavfsiz concurrency qoidalariga mos.
SnapKit yordamida UI yaratishda eng ko'p ishlatiladigan constraint'lar (chegaraviy bog'lamalar) asosan 4 ta guruhga bo'linadi: chetlar (edges), markaz (center), o'lchamlar (size) va oraliq masofalar (offset/inset). Ushbu darsda biz bu tushunchalarni chuqur o'rganamiz va SnapKit'dagi eng chalkash mavzu — offset va inset farqini ko'rib chiqamiz.
Mundarija
- Edge Constraints (Chetlar)
- Center Constraints (Markaz)
- Size Constraints (O'lchamlar)
- Offset vs Inset (Eng chalkash mavzu)
- EqualToSuperview() vs EqualTo()
- Amaliy loyiha: Login ekrani layouti
- Xulosa
- Manbalar
1. Edge Constraints (Chetlar) {#edges}
Elementni ekranning yoki boshqa view'ning chetlariga yopishtirish eng keng tarqalgan holatdir. SnapKit buning uchun juda qulay sintaksisni taqdim etadi.
Alohida chetlar
Siz har bir chetni alohida belgilashingiz mumkin:
import UIKit
import SnapKit
@MainActor
final class EdgeExampleView: UIView {
private let boxView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
setupConstraints()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupSubviews() {
boxView.backgroundColor = .systemBlue
addSubview(boxView)
}
private func setupConstraints() {
boxView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.leading.equalToSuperview().offset(16)
make.trailing.equalToSuperview().offset(-16)
make.bottom.equalToSuperview().offset(-20)
}
}
}
Barcha 4 ta chetni bir vaqtda belgilash (edges)
Yuqoridagi kodni make.edges yordamida ancha qisqartirish mumkin:
// 4 chetni ota view'ga yopishtirish
make.edges.equalToSuperview()
// Hamma tomondan bir xil 16pt masofa tashlash (padding)
make.edges.equalToSuperview().inset(16)
// Har bir tomon uchun turlicha masofa tashlash
make.edges.equalToSuperview().inset(UIEdgeInsets(top: 20, left: 16, bottom: 20, right: 16))
Senior eslatmasi:
left/rightvaleading/trailingo'rtasidagi farqni bilish juda muhim. *left/right— Har doim ekranning chap va o'ng tomoni (absolyut). *leading/trailing— Matn o'qilish yo'nalishiga qarab o'zgaradi. Masalan, RTL (o'ngdan chapga o'qiladigan Arab, Ibroniy) tillaridaleadingo'ng tomonga,trailingesa chap tomonga aylanadi. Doimoleading/trailingishlatish tavsiya etiladi! SnapKit'dadirectionalEdgesorqali RTL-safe layout'larni bir qatorda yozish mumkin:make.directionalEdges.equalToSuperview().inset(16)(leading, trailing, top, bottom bo'yicha ishlaydi).
2. Center Constraints (Markaz) {#center}
UI elementlarni ekranning yoki biror konteynerning o'rtasiga joylashtirish:
import UIKit
import SnapKit
@MainActor
final class CenterExampleView: UIView {
private let logoImageView = UIImageView()
// ... setupSubviews ...
private func setupConstraints() {
logoImageView.snp.makeConstraints { make in
// Ham gorizontal, ham vertikal markaz
make.center.equalToSuperview()
// YOKI faqat gorizontal markaz (X o'qi):
// make.centerX.equalToSuperview()
// YOKI faqat vertikal markaz (Y o'qi) va uni 50pt pastroqqa surish:
// make.centerY.equalToSuperview().offset(50)
// YOKI Boshqa view'ning markaziga bog'lash:
// make.center.equalTo(otherView)
}
}
}
3. Size Constraints (O'lchamlar) {#size}
View o'lchamlarini berish uchun width, height yoki size dan foydalaniladi.
boxView.snp.makeConstraints { make in
// Aniq o'lchamlar (Constant)
make.width.equalTo(200)
make.height.equalTo(100)
// Yoki ikkalasini bitta qilib yozish (CGSize)
make.size.equalTo(CGSize(width: 200, height: 100))
// Kvadrat (width = 50, height = 50) qilish uchun bitta raqam berish kifoya
make.size.equalTo(50)
// Boshqa view'ga nisbatan o'lcham (ota view'ning eni bilan bir xil)
make.width.equalToSuperview()
// Boshqa view'ning o'lchami bilan tenglashish
// make.width.equalTo(otherView)
}
4. Offset vs Inset — eng chalkash mavzu! {#offset-inset}
Yangi o'rganayotganlarning 90% qismi offset va inset ni adashtiradi. Sababi ularning ishlash logikasi biroz farq qiladi.
- Offset — Elementni ekranning koordinatalar o'qi (X va Y) bo'ylab qayerga siljitishni belgilaydi.
- Musbat (Positive) qiymat: O'ngga va Pastga siljitadi.
- Manfiy (Negative) qiymat: Chapga va Tepaga siljitadi.
- Inset — Elementni o'zining chegaralaridan qanchaga ichkariga tortishni belgilaydi. U asosan padding (ichki bo'shliq) kabi ishlaydi. Musbat qiymat doimo "ichkariga" qarab harakatlantiradi.
Vizual tushuntirish
(0,0) Ota View koordinata boshi
+-------------------------------------------+
| ^ offset(20) |
| | inset(20) |
| +-----------+ |
| | | |
offset(20) <-- | Obyekt | --> offset(-20) |
inset(20) | | inset(20) |
| +-----------+ |
| | inset(20) |
| v offset(-20) |
+-------------------------------------------+
Ko'rib turganingizdek:
topuchunoffset(20)vainset(20)bir xil ishlaydi (ikkalasi ham pastga, ichkariga suradi).bottomuchunoffset(-20)ishlatish kerak, lekininsetbilan yozsangiz musbatinset(20)deb yozasiz (ichkariga qarab tortadi).
Farqlar jadvali
| Tomon (Edge) | Offset (20pt ichkariga surish) | Inset (20pt ichkariga surish) | Qaysi biri qulayroq? |
|---|---|---|---|
| Top | make.top...offset(20) | make.top...inset(20) | Farqi yo'q (offset mashhur) |
| Leading | make.leading...offset(20) | make.leading...inset(20) | Farqi yo'q (offset mashhur) |
| Trailing | make.trailing...offset(-20) | make.trailing...inset(20) | Inset (manfiy belgi kerak emas) |
| Bottom | make.bottom...offset(-20) | make.bottom...inset(20) | Inset (manfiy belgi kerak emas) |
| Edges | ishlatish qiyin | make.edges...inset(16) | Inset |
Muhim: Agarda faqat
bottomyokitrailingconstraint berayotgan bo'lsangiz va musbat raqamlar bilan fikrlash qulay bo'lsainset(N)foydalaning. Manfiy raqam yoqsaoffset(-N)foydalaning. Ammo barcha tomonlarga birdaniga masofa berish uchun (edges) doimoinsetfoydalaning.
5. EqualToSuperview() vs EqualTo() {#equal-to}
SnapKit'da bog'lamalarni (constraint) ikki xil usulda ulash mumkin:
**1. equalToSuperview()** — Elementni to'g'ridan-to'g'ri o'zi joylashgan ota (super) view'ga ulaydi. Siz ota view nomini yozishingiz shart emas.
make.centerX.equalToSuperview() // Ota view'ning markaziga
make.width.equalToSuperview() // Ota view bilan bir xil eni
**2. equalTo()** — Boshqa har qanday ob'ektga yoki raqamga (constant) ulash.
// 1. Raqamga (Constant) ulash
make.width.equalTo(100)
// 2. Boshqa View'ga ulash (avtomatik o'sha view'ning bir xil anchoriga ulanadi)
// Masalan, pastdagi kod: o'zining markazini boshqa view'ning markaziga ulaydi
make.center.equalTo(otherView)
// 3. Boshqa View'ning aniq anchoriga ulash
// Masalan, bu elementning tepa qismini, boshqa elementning PASTKI qismiga ulash:
make.top.equalTo(otherView.snp.bottom).offset(16)
6. Amaliy loyiha: Login ekrani layouti {#amaliy-loyiha}
Barcha o'rganganlarimizni jamlab, haqiqiy iOS dasturlaridagi kabi Login ekranini chizamiz.
import UIKit
import SnapKit
@MainActor
final class LoginView: UIView {
// MARK: - UI Elements
private let logoImageView: UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .systemGray5
iv.layer.cornerRadius = 16
return iv
}()
private let emailTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "Email"
tf.borderStyle = .roundedRect
return tf
}()
private let passwordTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "Password"
tf.isSecureTextEntry = true
tf.borderStyle = .roundedRect
return tf
}()
private let loginButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Login", for: .normal)
btn.backgroundColor = .systemBlue
btn.setTitleColor(.white, for: .normal)
btn.layer.cornerRadius = 8
return btn
}()
private let forgotPasswordLabel: UILabel = {
let lbl = UILabel()
lbl.text = "Forgot password?"
lbl.textColor = .systemBlue
lbl.font = .systemFont(ofSize: 14)
return lbl
}()
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .systemBackground
setupSubviews()
setupConstraints()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
// MARK: - Setup
private func setupSubviews() {
addSubview(logoImageView)
addSubview(emailTextField)
addSubview(passwordTextField)
addSubview(loginButton)
addSubview(forgotPasswordLabel)
}
private func setupConstraints() {
// Logo markazda (tepaga yaqinroq) va aniq o'lchamda
logoImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(60)
make.size.equalTo(100) // 100x100 kvadrat
}
// Email maydoni: logonning pastida, chap/o'ngdan 24pt masofa
emailTextField.snp.makeConstraints { make in
make.top.equalTo(logoImageView.snp.bottom).offset(40)
make.leading.trailing.equalToSuperview().inset(24) // offset ishlatganda trailing -24 bo'lardi!
make.height.equalTo(50)
}
// Parol maydoni: email'ning tagida, o'lchamlari email bilan bir xil
passwordTextField.snp.makeConstraints { make in
make.top.equalTo(emailTextField.snp.bottom).offset(16)
make.leading.trailing.height.equalTo(emailTextField) // Kod qisqarishi!
}
// Parolni unutdingizmi: parol maydoni ostida, o'ng tomonga yopishtirilgan
forgotPasswordLabel.snp.makeConstraints { make in
make.top.equalTo(passwordTextField.snp.bottom).offset(12)
make.trailing.equalTo(passwordTextField.snp.trailing)
// height / width berish shart emas, UILabel o'z contentSize'iga ega
}
// Login tugmasi: parolni unutdingizmi label'i tagida
loginButton.snp.makeConstraints { make in
make.top.equalTo(forgotPasswordLabel.snp.bottom).offset(30)
make.leading.trailing.equalToSuperview().inset(24)
make.height.equalTo(50)
}
}
}
Bu kodda SnapKit'ning kuchi yaqqol ko'rinadi: make.leading.trailing.height.equalTo(emailTextField) kabi zanjirli (chained) yozish usuli bilan juda ko'p qator kodlarni bitta qatorga qisqartirdik.
Xulosa {#xulosa}
Ushbu darsda biz SnapKit'ning asosiy ustunlari bo'lgan chetlar, markazlar va o'lchamlarni belgilashni ko'rib chiqdik. Shuningdek, ko'pchilik xato qiladigan offset va inset orasidagi farqni vizual ravishda tushundik. Ushbu vositalar yordamida siz deyarli istalgan murakkablikdagi dizaynni aniq va tushunarli qilib yozishingiz mumkin.