SnapKit 15: Amaliyot — 30 ta Vizual UI Topshiriq (Zero to Hero Challenge)
🧩 SnapKit — Zero to Hero
SnapKit 15: Amaliyot — 30 ta Vizual UI Topshiriq (Zero to Hero Challenge)
Holat: Ushbu qo'llanma 2026-yil oktabr holatiga ko'ra SnapKit 5.7+ va Swift 6 talablari asosida tayyorlangan. Barcha kodlar zamonaviy
@MainActor, UIKit Auto Layout va SwiftUI ekvivalentlari bilan boyitilgan.
Auto Layout va SnapKit bo'yicha nazariy bilimlarni o'rganish — bu yo'lning atigi 30% qismi. Haqiqiy mahorat faqat va faqat amaliyot orqali shakllanadi. Professional iOS dasturchisi dizayner chizgan har qanday UI sxemani ko'rishi bilanoq miyasida constraint'lar zanjirini qurishi, qaysi element qaysi biriga bog'lanishini, qaysi biri qisqarib qaysi biri cho'zilishini darhol his qila olishi zarur.
Ushbu amaliy darsda siz uchun 30 ta maxsus vizual topshiriq tayyorlandi. Ular oddiy poydevordan boshlanib, real App Store ilovalaridagi eng murakkab interfeyslargacha (ProfileView, HomeView, Chat, Fintech, Food Delivery, Crypto, App Store Today, Fitness, Checkout, Full Podcast Player) bosqichma-bosqich qiyinlashib boradi.
🧭 Mashg'ulot Qoidalari va Tavsiyalar
- Avval mustaqil bajaring: Har bir topshiriqdagi grafik sxemani (rasmni) va texnik talablarni diqqat bilan o'rganing. Yechimni ochishdan oldin yangi Xcode Playground yoki loyihada kod yozib ko'ring.
- Kodni tekshiring: Agar yechimni topishda qiyinchilikka duch kelsangiz yoki o'z kodingizni eng toza arxitektura bilan solishtirmoqchi bo'lsangiz, "💡 Kodni ko'rish" tugmasini bosing.
- Uchala texnologiyani taqqoslang: Har bir vazifada sizga 3 xil yechim taqdim etiladi:
- SnapKit (Asosiy maqsadimiz): Minimal, o'qilishi oson va qulay DSL.
- Klassik UIKit (NSLayoutConstraint): Nativ Anchor tizimi (SnapKit qanchalik mehnatni tejashini ko'rish uchun).
- SwiftUI ekvivalenti: Zamonaviy deklarativ yondashuv (dunyoqarashni kengaytirish uchun).
- Pro Tip va arxitektura xulosalariga e'tibor bering: Har bir yechim ostidagi professional maslahatlar sizni intervyularda yoki katta loyihalarda uchraydigan constraint buzilishlaridan asraydi.
📊 Qiyinchilik Darajalari
| Daraja | Vazifalar | Qamrab Olingan Mavzular |
|---|---|---|
| 🟢 Oson (Easy) | 01 – 05 | Center, Edges Inset, Vertical Spacing, Safe Area, Avatar & Label |
| 🟡 O'rta (Medium) | 06 – 11 | Aspect Ratio (16:9), Overlapping Badge, Dynamic Width (Chat Bubble), 3 Equal Columns, Hugging/Compression Priority, Notification Banner |
| 🟠 Qiyin (Hard) | 12 – 16 | E-Commerce Product Card, Floating Action Button (FAB), Dynamic Self-Sizing Cell, UIScrollView va ContentView, Segmented Moving Indicator |
| 🔴 Qahramon (Hero) | 17 – 20 | Apple Music/Spotify Mini-Player, Instagram Stories Concentric Rings, Bank Card (1.586 ratio), Modern Paywall Subscription Card |
| 👑 Titan (Real-World Screens) | 21 – 30 | Instagram Profile, E-Commerce Home Feed, Telegram Chat Room, Fintech Banking, Food Delivery Detail, Crypto Order Book, App Store Today, Fitness Dashboard, Checkout Summary, Full Podcast Player |
🟢 Topshiriq 01: Markazdagi Kvadrat (Center Square)
Daraja:
Oson (Easy)| Maqsad: Ekran markazida o'zgarmas 120x120 o'lchamli kvadrat shaklidagi view'ni joylashtirish.
Ushbu topshiriq SnapKit'dagi eng asosiy poydevor tushunchalar: center (markazlashtirish) va size (aniq o'lcham belgilash) bilan ishlashni mustahkamlaydi.
Vizual Sxema (UI Mockup)
Topshiriq 01: Markazdagi Kvadrat (Center Square)
📋 Texnik Talablar va Cheklovlar
- Kvadrat kengligi (width) va balandligi (height) aynan 120 pt bo'lishi kerak.
- Kvadrat ota-ona (superview) ekranning gorizontal va vertikal markazida bo'lishi shart.
- Burchaklar radiusi (cornerRadius): 16 pt.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task01View: UIView {
private let blueBox: UIView = {
let view = UIView()
view.backgroundColor = .systemBlue
view.layer.cornerRadius = 16
view.clipsToBounds = true
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(blueBox)
blueBox.snp.makeConstraints { make in
make.center.equalToSuperview()
make.size.equalTo(120) // make.width.height.equalTo(120) bilan bir xil
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task01UIKitView: UIView {
private let blueBox: UIView = {
let view = UIView()
view.backgroundColor = .systemBlue
view.layer.cornerRadius = 16
view.clipsToBounds = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(blueBox)
NSLayoutConstraint.activate([
blueBox.centerXAnchor.constraint(equalTo: centerXAnchor),
blueBox.centerYAnchor.constraint(equalTo: centerYAnchor),
blueBox.widthAnchor.constraint(equalToConstant: 120),
blueBox.heightAnchor.constraint(equalToConstant: 120)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task01SwiftUIView: View {
var body: some View {
ZStack {
Color(white: 0.1).ignoresSafeArea()
RoundedRectangle(cornerRadius: 16)
.fill(Color.blue)
.frame(width: 120, height: 120)
}
}
}
💡 Pro Tip & Arxitektura siri: SnapKit'da
make.size.equalTo(120)deb yozishmake.width.equalTo(120)vamake.height.equalTo(120)o'rnini bosadi. Agar eni va bo'yi har xil bo'lsa,make.size.equalTo(CGSize(width: 120, height: 80))formatida berish mumkin.
</details>
🟢 Topshiriq 02: Chetlaridan Bir Xil Masofadagi Card (Edges Inset)
Daraja:
Oson (Easy)| Maqsad: Ekranning to'rtta chetidan ham 20 pt masofa (padding) tashlab, to'liq cho'ziluvchi kartani hosil qilish.
To'rtta chetni (top, bottom, leading, trailing) alohida yozish o'rniga SnapKit'ning kuchli edges va inset sintaksisidan foydalanish ko'nikmasi.
Vizual Sxema (UI Mockup)
Topshiriq 02: Chetlaridan Bir Xil Masofadagi Card (Edges Inset)
📋 Texnik Talablar va Cheklovlar
- Karta ota-onaning barcha 4 tomoniga (top, bottom, leading, trailing) bog'lanishi kerak.
- Har bir chetdan aynan 20 pt ichkariga (inset) siljishi lozim.
- Burchaklar radiusi: 14 pt, fon rangi: binafsha (systemPurple).
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task02View: UIView {
private let contentCard: UIView = {
let view = UIView()
view.backgroundColor = .systemPurple
view.layer.cornerRadius = 14
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(contentCard)
contentCard.snp.makeConstraints { make in
// Barcha 4 tomonni bir qatorda 20 pt ichkariga siljitish:
make.edges.equalToSuperview().inset(20)
// Yoki alohida insets:
// make.edges.equalToSuperview().inset(UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20))
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task02UIKitView: UIView {
private let contentCard: UIView = {
let view = UIView()
view.backgroundColor = .systemPurple
view.layer.cornerRadius = 14
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(contentCard)
NSLayoutConstraint.activate([
contentCard.topAnchor.constraint(equalTo: topAnchor, constant: 20),
contentCard.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
contentCard.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20),
contentCard.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task02SwiftUIView: View {
var body: some View {
ZStack {
Color(white: 0.1).ignoresSafeArea()
RoundedRectangle(cornerRadius: 14)
.fill(Color.purple)
.padding(20)
}
}
}
💡 Pro Tip & Arxitektura siri: Farqiga e'tibor bering:
inset(20)deb yozganda SnapKittrailingvabottomuchun avtomatik ravishda manfiy ishora (-20) qo'llaydi. Agar sizoffset(20)ishlatganingizda edi, pastki va o'ng chegaralar ekrandan tashqariga chiqib ketardi!
</details>
🟢 Topshiriq 03: Ketma-ket Ikkita Vertikal Karta (Spacing)
Daraja:
Oson (Easy)| Maqsad: Biri ikkinchisining ostida joylashgan, orasi 16 pt bo'lgan ikkita kartani bog'lash.
Elementlar orasidagi munosabat: ikkinchi elementning yuqori qismini (top) birinchi elementning pastki qismiga (bottom) bog'lash amaliyoti.
Vizual Sxema (UI Mockup)
Topshiriq 03: Ketma-ket Ikkita Vertikal Karta (Spacing)
📋 Texnik Talablar va Cheklovlar
- Ikkala karta kengligi ota-onaning yonlaridan 24 pt masofada bo'lsin.
- Har bir kartaning balandligi aynan 85 pt.
- Birinchi karta ota-onaning tepasidan 35 pt masofada.
- Ikkinchi karta birinchi kartaning tagidan 16 pt oraliq bilan joylashsin.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task03View: UIView {
private let topCard: UIView = {
let v = UIView()
v.backgroundColor = .systemBlue
v.layer.cornerRadius = 12
return v
}()
private let bottomCard: UIView = {
let v = UIView()
v.backgroundColor = .systemPurple
v.layer.cornerRadius = 12
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(topCard)
addSubview(bottomCard)
topCard.snp.makeConstraints { make in
make.top.equalToSuperview().offset(35)
make.leading.trailing.equalToSuperview().inset(24)
make.height.equalTo(85)
}
bottomCard.snp.makeConstraints { make in
make.top.equalTo(topCard.snp.bottom).offset(16)
make.leading.trailing.equalTo(topCard) // topCard bilan bir xil kenglik
make.height.equalTo(85)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task03UIKitView: UIView {
private let topCard: UIView = {
let v = UIView()
v.backgroundColor = .systemBlue
v.layer.cornerRadius = 12
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
private let bottomCard: UIView = {
let v = UIView()
v.backgroundColor = .systemPurple
v.layer.cornerRadius = 12
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(topCard)
addSubview(bottomCard)
NSLayoutConstraint.activate([
topCard.topAnchor.constraint(equalTo: topAnchor, constant: 35),
topCard.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 24),
topCard.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -24),
topCard.heightAnchor.constraint(equalToConstant: 85),
bottomCard.topAnchor.constraint(equalTo: topCard.bottomAnchor, constant: 16),
bottomCard.leadingAnchor.constraint(equalTo: topCard.leadingAnchor),
bottomCard.trailingAnchor.constraint(equalTo: topCard.trailingAnchor),
bottomCard.heightAnchor.constraint(equalToConstant: 85)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task03SwiftUIView: View {
var body: some View {
VStack(spacing: 16) {
RoundedRectangle(cornerRadius: 12)
.fill(Color.blue)
.frame(height: 85)
RoundedRectangle(cornerRadius: 12)
.fill(Color.purple)
.frame(height: 85)
Spacer()
}
.padding(.horizontal, 24)
.padding(.top, 35)
.background(Color(white: 0.1).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: SnapKit'da
make.leading.trailing.equalTo(topCard)deb yozish bir yo'la ikkita chetni bir xil qilib bog'laydi. Bu kodni ixchamlashtiradi va kelajakdatopCardning marginlari o'zgarsa,bottomCardham avtomatik ergashadi.
</details>
🟢 Topshiriq 04: Bosh Banner va Pastki Qadalgan Tugma (Safe Area)
Daraja:
Oson (Easy)| Maqsad: Yuqoridagi bannerni Safe Area tepasiga, pastki tugmani esa Safe Area pastki chegarasiga mustahkamlash.
iPhone'dagi Dynamic Island, Notch va pastki Home Bar tugmalari bilan to'qnash kelmaslik uchun safeAreaLayoutGuide bilan to'g'ri ishlash.
Vizual Sxema (UI Mockup)
Topshiriq 04: Bosh Banner va Pastki Qadalgan Tugma (Safe Area)
📋 Texnik Talablar va Cheklovlar
- Header banner Safe Area tepasidan 8 pt pastda, balandligi 56 pt.
- Bottom action button Safe Area ostidan 8 pt tepada, balandligi 48 pt, burchaklari 24 pt (pill shape).
- Ikkala element ham yondan 16 pt masofada bo'lsin.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task04ViewController: UIViewController {
private let headerBanner: UIView = {
let v = UIView()
v.backgroundColor = UIColor(white: 0.2, alpha: 1.0)
v.layer.cornerRadius = 10
return v
}()
private let continueButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Davom etish", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 15, weight: .bold)
btn.backgroundColor = .systemBlue
btn.layer.cornerRadius = 24
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(white: 0.08, alpha: 1.0)
view.addSubview(headerBanner)
view.addSubview(continueButton)
headerBanner.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(8)
make.leading.trailing.equalToSuperview().inset(16)
make.height.equalTo(56)
}
continueButton.snp.makeConstraints { make in
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-8)
make.leading.trailing.equalToSuperview().inset(16)
make.height.equalTo(48)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task04UIKitViewController: UIViewController {
private let headerBanner: UIView = {
let v = UIView()
v.backgroundColor = UIColor(white: 0.2, alpha: 1.0)
v.layer.cornerRadius = 10
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
private let continueButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Davom etish", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = .systemBlue
btn.layer.cornerRadius = 24
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(white: 0.08, alpha: 1.0)
view.addSubview(headerBanner)
view.addSubview(continueButton)
let safe = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
headerBanner.topAnchor.constraint(equalTo: safe.topAnchor, constant: 8),
headerBanner.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
headerBanner.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
headerBanner.heightAnchor.constraint(equalToConstant: 56),
continueButton.bottomAnchor.constraint(equalTo: safe.bottomAnchor, constant: -8),
continueButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
continueButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
continueButton.heightAnchor.constraint(equalToConstant: 48)
])
}
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task04SwiftUIView: View {
var body: some View {
VStack {
RoundedRectangle(cornerRadius: 10)
.fill(Color(white: 0.2))
.frame(height: 56)
.padding(.top, 8)
.padding(.horizontal, 16)
Spacer()
Button(action: {}) {
Text("Davom etish")
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.frame(height: 48)
.background(Color.blue)
.clipShape(Capsule())
}
.padding(.bottom, 8)
.padding(.horizontal, 16)
}
.background(Color(white: 0.08).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: SnapKit'da
view.safeAreaLayoutGuide.snp.toporqali to'g'ridan-to'g'ri bog'lanish eng xavfsiz yo'ldir. Hech qachon ekranning mutlaqtopchegarasiga fiksatsiyalangan raqam bermang, chunki iPhone SE (notch yo'q), iPhone 13 (notch bor) va iPhone 15/16 (Dynamic Island) har xil balandlikka ega!
</details>
🟢 Topshiriq 05: Doiraviy Profil Rasmi va Yonidagi Matn
Daraja:
Oson (Easy)| Maqsad: Chap tomonda 64x64 doiraviy avatar, uning o'ng tomonida esa vertikal markazlashgan Title va Subtitle yozuvlarini hosil qilish.
Gorizontal zanjir (Avatar -> Text) va matnlar guruhini umumiy konteyner yoki avatarga nisbatan vertikal markazlashtirish usuli.
Vizual Sxema (UI Mockup)
Topshiriq 05: Doiraviy Profil Rasmi va Yonidagi Matn
📋 Texnik Talablar va Cheklovlar
- Avatar: 64x64 pt, burchak radiusi 32 pt (to'liq doira), chapdan 16 pt.
- Matnlar avatardan 12 pt o'ngda boshlansin.
- Title: qalin 15 pt matn. Subtitle: och 12 pt matn, title'dan 4 pt pastda.
- Title va Subtitle juftligi avatarga nisbatan vertikal markazlashgan bo'lsin.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task05View: UIView {
private let avatarImageView: UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .systemBlue
iv.layer.cornerRadius = 32
iv.clipsToBounds = true
return iv
}()
private let titleLabel: UILabel = {
let l = UILabel()
l.text = "Azimjon Pulatov"
l.textColor = .white
l.font = .systemFont(ofSize: 15, weight: .bold)
return l
}()
private let subtitleLabel: UILabel = {
let l = UILabel()
l.text = "iOS Software Engineer"
l.textColor = .systemGray
l.font = .systemFont(ofSize: 12, weight: .regular)
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(avatarImageView)
addSubview(titleLabel)
addSubview(subtitleLabel)
avatarImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.equalToSuperview().offset(16)
make.size.equalTo(64)
}
titleLabel.snp.makeConstraints { make in
make.leading.equalTo(avatarImageView.snp.trailing).offset(12)
make.trailing.lessThanOrEqualToSuperview().offset(-16)
make.bottom.equalTo(avatarImageView.snp.centerY).offset(-2)
}
subtitleLabel.snp.makeConstraints { make in
make.leading.equalTo(titleLabel)
make.trailing.lessThanOrEqualToSuperview().offset(-16)
make.top.equalTo(avatarImageView.snp.centerY).offset(2)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task05UIKitView: UIView {
private let avatarImageView: UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .systemBlue
iv.layer.cornerRadius = 32
iv.clipsToBounds = true
iv.translatesAutoresizingMaskIntoConstraints = false
return iv
}()
private let titleLabel: UILabel = {
let l = UILabel()
l.text = "Azimjon Pulatov"
l.textColor = .white
l.font = .systemFont(ofSize: 15, weight: .bold)
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
private let subtitleLabel: UILabel = {
let l = UILabel()
l.text = "iOS Software Engineer"
l.textColor = .systemGray
l.font = .systemFont(ofSize: 12, weight: .regular)
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(avatarImageView)
addSubview(titleLabel)
addSubview(subtitleLabel)
NSLayoutConstraint.activate([
avatarImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
avatarImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
avatarImageView.widthAnchor.constraint(equalToConstant: 64),
avatarImageView.heightAnchor.constraint(equalToConstant: 64),
titleLabel.leadingAnchor.constraint(equalTo: avatarImageView.trailingAnchor, constant: 12),
titleLabel.bottomAnchor.constraint(equalTo: avatarImageView.centerYAnchor, constant: -2),
subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
subtitleLabel.topAnchor.constraint(equalTo: avatarImageView.centerYAnchor, constant: 2)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task05SwiftUIView: View {
var body: some View {
HStack(spacing: 12) {
Circle()
.fill(Color.blue)
.frame(width: 64, height: 64)
VStack(alignment: .leading, spacing: 4) {
Text("Azimjon Pulatov")
.font(.system(size: 15, weight: .bold))
.foregroundColor(.white)
Text("iOS Software Engineer")
.font(.system(size: 12))
.foregroundColor(.gray)
}
Spacer()
}
.padding(.horizontal, 16)
.frame(height: 96)
.background(Color(white: 0.1).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: Ikkita satrli matnni vertikal markazlashtirishning ajoyib usuli:
titleLabel.bottomni markaz chizig'iga (centerY.offset(-2)),subtitleLabel.topni esa markaz chizig'iga (centerY.offset(2)) bog'lashdir. Bu hech qanday qo'shimcha container view talab qilmaydi!
</details>
🟡 Topshiriq 06: 16:9 Nisbatdagi Video Player Karta
Daraja:
O'rta (Medium)| Maqsad: Ekran kengligiga moslashuvchan, balandligi esa har doim 16:9 nisbatda avtomatik saqlanib turuvchi video player container yaratish.
SnapKit'dagi multipliedBy yordamida ekranning har qanday kengligida (iPhone, iPad, Landscape) to'g'ri proporsiyani saqlash texnikasi.
Vizual Sxema (UI Mockup)
Topshiriq 06: 16:9 Nisbatdagi Video Player Karta
📋 Texnik Talablar va Cheklovlar
- Video kartasi yonlardan 24 pt masofa bilan ota-onaga bog'lansin.
- Balandlik (height) kenglikka (width) nisbatan qat'iy 9/16 (0.5625) ko'paytuvchisi bilan o'rnatilsin.
- Karta markazida 48x48 o'lchamdagi play tugmasi doirasi bo'lsin.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task06View: UIView {
private let videoPlayerCard: UIView = {
let v = UIView()
v.backgroundColor = UIColor(white: 0.15, alpha: 1.0)
v.layer.cornerRadius = 12
v.layer.borderWidth = 1.5
v.layer.borderColor = UIColor.systemGreen.cgColor
return v
}()
private let playButton: UIButton = {
let btn = UIButton(type: .system)
let config = UIImage.SymbolConfiguration(pointSize: 22, weight: .bold)
btn.setImage(UIImage(systemName: "play.fill", withConfiguration: config), for: .normal)
btn.tintColor = .white
btn.backgroundColor = .systemGreen
btn.layer.cornerRadius = 24
return btn
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
addSubview(videoPlayerCard)
videoPlayerCard.addSubview(playButton)
videoPlayerCard.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.trailing.equalToSuperview().inset(24)
// 16:9 Aspect Ratio: balandlik = kenglik * (9.0 / 16.0)
make.height.equalTo(videoPlayerCard.snp.width).multipliedBy(9.0 / 16.0)
}
playButton.snp.makeConstraints { make in
make.center.equalToSuperview()
make.size.equalTo(48)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task06UIKitView: UIView {
private let videoPlayerCard: UIView = {
let v = UIView()
v.backgroundColor = UIColor(white: 0.15, alpha: 1.0)
v.layer.cornerRadius = 12
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
addSubview(videoPlayerCard)
NSLayoutConstraint.activate([
videoPlayerCard.centerYAnchor.constraint(equalTo: centerYAnchor),
videoPlayerCard.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 24),
videoPlayerCard.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -24),
// UIKit'da multiplier yordamida aspect ratio:
videoPlayerCard.heightAnchor.constraint(
equalTo: videoPlayerCard.widthAnchor,
multiplier: 9.0 / 16.0
)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task06SwiftUIView: View {
var body: some View {
ZStack {
Color(white: 0.08).ignoresSafeArea()
ZStack {
RoundedRectangle(cornerRadius: 12)
.fill(Color(white: 0.15))
.aspectRatio(16/9, contentMode: .fit)
Circle()
.fill(Color.green)
.frame(width: 48, height: 48)
.overlay(
Image(systemName: "play.fill")
.foregroundColor(.white)
)
}
.padding(.horizontal, 24)
}
}
}
💡 Pro Tip & Arxitektura siri: Nisbat belgilashda Swift'dagi bo'lish amalini ehtiyotkorlik bilan yozing:
9 / 16butun sonli bo'lish bo'lgani uchun natija 0 bo'lib qoladi! Doimo float formatda9.0 / 16.0yozishni unutmang.
</details>
🟡 Topshiriq 07: Profil Rasmi Burchagidagi Online Status Dot
Daraja:
O'rta (Medium)| Maqsad: 80x80 profil rasmining pastki o'ng burchagida qisman chiqib turuvchi 24x24 online status nishonini (badge) joylashtirish.
Elementlarni bir-birining ustiga (overlap) qadash va burchak koordinatalarini nozik offset bilan surish amaliyoti.
Vizual Sxema (UI Mockup)
Topshiriq 07: Profil Rasmi Burchagidagi Online Status Dot
📋 Texnik Talablar va Cheklovlar
- Avatar: 80x80 pt o'lcham, burchak radiusi 40 pt.
- Status badge: 24x24 pt, yashil rang, oq yoki to'q chegara (border: 3 pt).
- Status badge markazi avatarning pastki o'ng chetidan 2 pt tashqariga siljisin.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task07View: UIView {
private let avatarImageView: UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .systemPurple
iv.layer.cornerRadius = 40
iv.clipsToBounds = true
return iv
}()
private let statusDot: UIView = {
let v = UIView()
v.backgroundColor = .systemGreen
v.layer.cornerRadius = 12
v.layer.borderWidth = 3
v.layer.borderColor = UIColor(white: 0.1, alpha: 1.0).cgColor
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(avatarImageView)
addSubview(statusDot) // statusDot avatardan ustun turishi uchun keyin qo'shiladi
avatarImageView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.size.equalTo(80)
}
statusDot.snp.makeConstraints { make in
make.size.equalTo(24)
// Avatarning pastki-o'ng burchagiga mahkamlash:
make.bottom.equalTo(avatarImageView.snp.bottom).offset(2)
make.trailing.equalTo(avatarImageView.snp.trailing).offset(2)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task07UIKitView: UIView {
private let avatarImageView: UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .systemPurple
iv.layer.cornerRadius = 40
iv.clipsToBounds = true
iv.translatesAutoresizingMaskIntoConstraints = false
return iv
}()
private let statusDot: UIView = {
let v = UIView()
v.backgroundColor = .systemGreen
v.layer.cornerRadius = 12
v.layer.borderWidth = 3
v.layer.borderColor = UIColor(white: 0.1, alpha: 1.0).cgColor
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(avatarImageView)
addSubview(statusDot)
NSLayoutConstraint.activate([
avatarImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
avatarImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
avatarImageView.widthAnchor.constraint(equalToConstant: 80),
avatarImageView.heightAnchor.constraint(equalToConstant: 80),
statusDot.widthAnchor.constraint(equalToConstant: 24),
statusDot.heightAnchor.constraint(equalToConstant: 24),
statusDot.bottomAnchor.constraint(equalTo: avatarImageView.bottomAnchor, constant: 2),
statusDot.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor, constant: 2)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task07SwiftUIView: View {
var body: some View {
ZStack {
Color(white: 0.1).ignoresSafeArea()
Circle()
.fill(Color.purple)
.frame(width: 80, height: 80)
.overlay(
Circle()
.fill(Color.green)
.frame(width: 24, height: 24)
.overlay(Circle().stroke(Color(white: 0.1), lineWidth: 3))
.offset(x: 2, y: 2),
alignment: .bottomTrailing
)
}
}
}
💡 Pro Tip & Arxitektura siri: Agar
avatarImageView.clipsToBounds = truebo'lsa va sizstatusDotni uning ichiga (avatarImageView.addSubview(statusDot)) qo'shsangiz, chetdan chiqib turgan qismi qirqilib ketadi! Shu sababli doimo badge'larni tashqi umumiy view'ga qo'shib, keyin avatarga bog'lang.
</details>
🟡 Topshiriq 08: Moslashuvchan Xabar Pufakchasi (Chat Bubble)
Daraja:
O'rta (Medium)| Maqsad: Telegram yoki iMessage kabi dinamik chat pufakchasini yaratish: qisqa matnda kichrayishi, lekin eng ko'p cho'zilganida ham ekran kengligining 75% idan oshmasligi kerak.
Tengsizliklar (greaterThanOrEqualTo va lessThanOrEqualTo) bilan ishlash mahorati.
Vizual Sxema (UI Mockup)
Topshiriq 08: Moslashuvchan Xabar Pufakchasi (Chat Bubble)
📋 Texnik Talablar va Cheklovlar
- Pufakcha chap chetdan 16 pt masofada.
- Minimal kenglik: 60 pt (
greaterThanOrEqualTo). - Maksimal kenglik: ota-ona kengligining 75% qismi (
lessThanOrEqualToSuperview().multipliedBy(0.75)). - Matn ko'p qatorli bo'lishi mumkin (
numberOfLines = 0), pufakcha ichidagi padding 12 pt.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task08View: UIView {
private let bubbleView: UIView = {
let v = UIView()
v.backgroundColor = .systemBlue
v.layer.cornerRadius = 16
return v
}()
private let messageLabel: UILabel = {
let l = UILabel()
l.text = "SnapKit yordamida Auto Layout yozish juda qulay va kod hajmini 3 baravar qisqartiradi!"
l.textColor = .white
l.font = .systemFont(ofSize: 15)
l.numberOfLines = 0
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
addSubview(bubbleView)
bubbleView.addSubview(messageLabel)
bubbleView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(60)
make.leading.equalToSuperview().offset(16)
// Cheklovlar:
make.width.greaterThanOrEqualTo(60)
make.width.lessThanOrEqualToSuperview().multipliedBy(0.75)
}
messageLabel.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(12)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task08UIKitView: UIView {
private let bubbleView: UIView = {
let v = UIView()
v.backgroundColor = .systemBlue
v.layer.cornerRadius = 16
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
private let messageLabel: UILabel = {
let l = UILabel()
l.text = "SnapKit yordamida Auto Layout yozish juda qulay va kod hajmini 3 baravar qisqartiradi!"
l.textColor = .white
l.font = .systemFont(ofSize: 15)
l.numberOfLines = 0
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
addSubview(bubbleView)
bubbleView.addSubview(messageLabel)
let maxConstraint = bubbleView.widthAnchor.constraint(
lessThanOrEqualTo: widthAnchor,
multiplier: 0.75
)
NSLayoutConstraint.activate([
bubbleView.topAnchor.constraint(equalTo: topAnchor, constant: 60),
bubbleView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
bubbleView.widthAnchor.constraint(greaterThanOrEqualToConstant: 60),
maxConstraint,
messageLabel.topAnchor.constraint(equalTo: bubbleView.topAnchor, constant: 12),
messageLabel.bottomAnchor.constraint(equalTo: bubbleView.bottomAnchor, constant: -12),
messageLabel.leadingAnchor.constraint(equalTo: bubbleView.leadingAnchor, constant: 12),
messageLabel.trailingAnchor.constraint(equalTo: bubbleView.trailingAnchor, constant: -12)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task08SwiftUIView: View {
var body: some View {
GeometryReader { proxy in
VStack(alignment: .leading) {
Text("SnapKit yordamida Auto Layout yozish juda qulay va kod hajmini 3 baravar qisqartiradi!")
.font(.system(size: 15))
.foregroundColor(.white)
.padding(12)
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 16))
.frame(
minWidth: 60,
maxWidth: proxy.size.width * 0.75,
alignment: .leading
)
}
.padding(.horizontal, 16)
.padding(.top, 60)
}
.background(Color(white: 0.08).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: Matn bir necha qator bo'lishi uchun
numberOfLines = 0bo'lishi shart. UILabel o'zining tabiiy o'lchamini (intrinsicContentSize) hisoblab chiqaradi va faqatgina 75% limitga urilgandagina keyingi satrga o'tadi.
</details>
🟡 Topshiriq 09: Uchta Teng Ustun (Three Equal Columns)
Daraja:
O'rta (Medium)| Maqsad: Gorizontal ravishda yonma-yon joylashgan, kengligi bir-biriga mutlaqo teng bo'lgan va orasi 16 pt dan bo'lgan 3 ta kartani hosil qilish.
Teng kengliklarni zanjir usulida bir-biriga tenglash (make.width.equalTo(card1)) va chekka chegaralarni to'g'ri yopish.
Vizual Sxema (UI Mockup)
Topshiriq 09: Uchta Teng Ustun (Three Equal Columns)
📋 Texnik Talablar va Cheklovlar
- 3 ta karta ekranning chap va o'ng chegarasidan 16 pt oraliqda bo'lsin.
- Kartalar orasidagi masofa aynan 16 pt.
- Har bir kartaning kengligi bir xil bo'lishi va balandligi 120 pt bo'lishi shart.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task09View: UIView {
private let card1 = UIView()
private let card2 = UIView()
private let card3 = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
[card1, card2, card3].enumerated().forEach { index, card in
card.backgroundColor = [UIColor.systemBlue, UIColor.systemPurple, UIColor.systemGreen][index]
card.layer.cornerRadius = 12
addSubview(card)
}
card1.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.equalToSuperview().offset(16)
make.height.equalTo(120)
}
card2.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.equalTo(card1.snp.trailing).offset(16)
make.width.equalTo(card1) // 1-karta bilan teng kenglik
make.height.equalTo(120)
}
card3.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.equalTo(card2.snp.trailing).offset(16)
make.trailing.equalToSuperview().offset(-16) // o'ng tomonga qadaladi
make.width.equalTo(card1) // 1-karta bilan teng kenglik
make.height.equalTo(120)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task09UIKitView: UIView {
private let card1 = UIView()
private let card2 = UIView()
private let card3 = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
[card1, card2, card3].enumerated().forEach { index, card in
card.backgroundColor = [UIColor.systemBlue, UIColor.systemPurple, UIColor.systemGreen][index]
card.layer.cornerRadius = 12
card.translatesAutoresizingMaskIntoConstraints = false
addSubview(card)
}
NSLayoutConstraint.activate([
card1.centerYAnchor.constraint(equalTo: centerYAnchor),
card1.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
card1.heightAnchor.constraint(equalToConstant: 120),
card2.centerYAnchor.constraint(equalTo: centerYAnchor),
card2.leadingAnchor.constraint(equalTo: card1.trailingAnchor, constant: 16),
card2.widthAnchor.constraint(equalTo: card1.widthAnchor),
card2.heightAnchor.constraint(equalToConstant: 120),
card3.centerYAnchor.constraint(equalTo: centerYAnchor),
card3.leadingAnchor.constraint(equalTo: card2.trailingAnchor, constant: 16),
card3.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
card3.widthAnchor.constraint(equalTo: card1.widthAnchor),
card3.heightAnchor.constraint(equalToConstant: 120)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task09SwiftUIView: View {
var body: some View {
HStack(spacing: 16) {
RoundedRectangle(cornerRadius: 12)
.fill(Color.blue)
.frame(height: 120)
RoundedRectangle(cornerRadius: 12)
.fill(Color.purple)
.frame(height: 120)
RoundedRectangle(cornerRadius: 12)
.fill(Color.green)
.frame(height: 120)
}
.padding(.horizontal, 16)
.background(Color(white: 0.08).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: Matematik formulaga e'tibor bering: 3 ta karta va 4 ta masofa (chap, 2 ta o'rtadagi, o'ng) berildi va oxirgi karta
trailingga qadalgach, Auto Layout har bir kartaning kengligini har qanday qurilma o'lchamida mustaqil hisoblab beradi.
</details>
🟡 Topshiriq 10: Sarlavha va Sana: Content Compression Resistance Priority
Daraja:
O'rta (Medium)| Maqsad: Bitta qatorda chapda sarlavha, o'ngda sana. Agar sarlavha matni haddan tashqari uzun bo'lib ketsa ham, sana hech qachon siqilib qisqarmasligi, aksincha sarlavha '...' (truncate) bo'lishi kerak.
Constraint Priority, Content Compression Resistance va Content Hugging tushunchalarini amalda hal qilish.
Vizual Sxema (UI Mockup)
Topshiriq 10: Sarlavha va Sana: Content Compression Resistance Priority
📋 Texnik Talablar va Cheklovlar
- titleLabel: chapda, uzayganda sig'may qolsa uch nuqta bo'lsin (
.byTruncatingTail). - dateLabel: o'ngda, hech qachon qisqarmasin va matni to'liq ko'rinsin.
- dateLabel'ning
contentCompressionResistancePrioritydarajasi.required(1000) ga ko'tarilsin, titleLabel'niki esa.defaultLow(250) bo'lsin.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task10View: UIView {
private let titleLabel: UILabel = {
let l = UILabel()
l.text = "Juda uzun topshiriq sarlavhasi: SnapKit va UIKit Auto Layout arxitekturasini o'rganish"
l.textColor = .white
l.font = .systemFont(ofSize: 15, weight: .semibold)
l.lineBreakMode = .byTruncatingTail
return l
}()
private let dateLabel: UILabel = {
let l = UILabel()
l.text = "Bugun, 18:30"
l.textColor = .systemBlue
l.font = .systemFont(ofSize: 13, weight: .bold)
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(titleLabel)
addSubview(dateLabel)
// Sanani siqilishdan qutqaruvchi kalit qator:
dateLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
titleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
titleLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.equalToSuperview().offset(16)
make.trailing.lessThanOrEqualTo(dateLabel.snp.leading).offset(-12)
}
dateLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.trailing.equalToSuperview().offset(-16)
}
}
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task10UIKitView: UIView {
private let titleLabel: UILabel = {
let l = UILabel()
l.text = "Juda uzun topshiriq sarlavhasi: SnapKit va UIKit Auto Layout arxitekturasini o'rganish"
l.textColor = .white
l.font = .systemFont(ofSize: 15, weight: .semibold)
l.lineBreakMode = .byTruncatingTail
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
private let dateLabel: UILabel = {
let l = UILabel()
l.text = "Bugun, 18:30"
l.textColor = .systemBlue
l.font = .systemFont(ofSize: 13, weight: .bold)
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
addSubview(titleLabel)
addSubview(dateLabel)
dateLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
titleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
NSLayoutConstraint.activate([
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: dateLabel.leadingAnchor, constant: -12),
dateLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
dateLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task10SwiftUIView: View {
var body: some View {
HStack(spacing: 12) {
Text("Juda uzun topshiriq sarlavhasi: SnapKit va UIKit Auto Layout arxitekturasini o'rganish")
.font(.system(size: 15, weight: .semibold))
.foregroundColor(.white)
.lineLimit(1)
.truncationMode(.tail)
Text("Bugun, 18:30")
.font(.system(size: 13, weight: .bold))
.foregroundColor(.blue)
.fixedSize(horizontal: true, vertical: false) // Siqilishdan himoya
}
.padding(.horizontal, 16)
.frame(height: 60)
.background(Color(white: 0.1).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: Intervyularda eng ko'p beriladigan savol: 'Ikki label yonma-yon turganda qaysi biri qisqarishini qanday boshqarasiz?' Javob:
setContentCompressionResistancePriorityorqali. Qaysi view'ning priority'si kichik bo'lsa (250), o'sha view birinchi bo'lib qisqaradi!
</details>
🟡 Topshiriq 11: Bildirishnoma Kartasi va Yopish Tugmasi
Daraja:
O'rta (Medium)| Maqsad: Ekranning yuqorisida bildirishnoma banneri: chapda 36x36 icon, o'rtada 2 qatorli xabar matni, o'ngda esa 28x28 yopish tugmasi ('✕').
Uchta elementdan iborat gorizontal zanjir (Icon -> Flexible Text Stack -> Action Button) va ularni to'g'ri oraliqlar bilan joylashtirish.
Vizual Sxema (UI Mockup)
Topshiriq 11: Bildirishnoma Kartasi va Yopish Tugmasi
📋 Texnik Talablar va Cheklovlar
- Banner: balandligi 80 pt, chetlaridan 16 pt oraliq, burchaklar radiusi 14 pt.
- IconView: 36x36 pt, chapdan 16 pt, vertikal markazda.
- CloseButton: 28x28 pt, o'ngdan 16 pt, vertikal markazda.
- Matnlar maydoni Icon va CloseButton oralig'ini to'liq egallasin (orasi 12 pt dan).
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit
final class Task11View: UIView {
private let bannerCard: UIView = {
let v = UIView()
v.backgroundColor = UIColor(white: 0.15, alpha: 1.0)
v.layer.cornerRadius = 14
v.layer.borderWidth = 1
v.layer.borderColor = UIColor.systemSky?.cgColor ?? UIColor.systemBlue.cgColor
return v
}()
private let iconImageView: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(systemName: "bell.badge.fill")
iv.tintColor = .systemSky ?? .systemBlue
iv.contentMode = .scaleAspectFit
return iv
}()
private let titleLabel: UILabel = {
let l = UILabel()
l.text = "Yangi topshiriq tayyor"
l.textColor = .white
l.font = .systemFont(ofSize: 14, weight: .bold)
return l
}()
private let bodyLabel: UILabel = {
let l = UILabel()
l.text = "SnapKit kursidan 20 ta amaliy vazifani boshlang."
l.textColor = .systemGray
l.font = .systemFont(ofSize: 11)
l.numberOfLines = 2
return l
}()
private let closeButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("✕", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 13, weight: .bold)
btn.backgroundColor = UIColor(white: 0.25, alpha: 1.0)
btn.layer.cornerRadius = 14
return btn
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupUI() {
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
addSubview(bannerCard)
bannerCard.addSubview(iconImageView)
bannerCard.addSubview(titleLabel)
bannerCard.addSubview(bodyLabel)
bannerCard.addSubview(closeButton)
bannerCard.snp.makeConstraints { make in
make.top.equalToSuperview().offset(60)
make.leading.trailing.equalToSuperview().inset(16)
make.height.equalTo(80)
}
iconImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.leading.equalToSuperview().offset(16)
make.size.equalTo(36)
}
closeButton.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.trailing.equalToSuperview().offset(-16)
make.size.equalTo(28)
}
titleLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(16)
make.leading.equalTo(iconImageView.snp.trailing).offset(12)
make.trailing.equalTo(closeButton.snp.leading).offset(-12)
}
bodyLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom).offset(4)
make.leading.trailing.equalTo(titleLabel)
}
}
}
private extension UIColor {
static var systemSky: UIColor? { UIColor(red: 0.22, green: 0.74, blue: 0.97, alpha: 1.0) }
}
2. Klassik UIKit (NSLayoutConstraint) Taqqoslash
import UIKit
final class Task11UIKitView: UIView {
private let bannerCard: UIView = {
let v = UIView()
v.backgroundColor = UIColor(white: 0.15, alpha: 1.0)
v.layer.cornerRadius = 14
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
private let iconImageView: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(systemName: "bell.badge.fill")
iv.tintColor = .systemBlue
iv.translatesAutoresizingMaskIntoConstraints = false
return iv
}()
private let titleLabel: UILabel = {
let l = UILabel()
l.text = "Yangi topshiriq tayyor"
l.textColor = .white
l.font = .systemFont(ofSize: 14, weight: .bold)
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
private let closeButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("✕", for: .normal)
btn.backgroundColor = UIColor(white: 0.25, alpha: 1.0)
btn.layer.cornerRadius = 14
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.08, alpha: 1.0)
addSubview(bannerCard)
bannerCard.addSubview(iconImageView)
bannerCard.addSubview(titleLabel)
bannerCard.addSubview(closeButton)
NSLayoutConstraint.activate([
bannerCard.topAnchor.constraint(equalTo: topAnchor, constant: 60),
bannerCard.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
bannerCard.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
bannerCard.heightAnchor.constraint(equalToConstant: 80),
iconImageView.centerYAnchor.constraint(equalTo: bannerCard.centerYAnchor),
iconImageView.leadingAnchor.constraint(equalTo: bannerCard.leadingAnchor, constant: 16),
iconImageView.widthAnchor.constraint(equalToConstant: 36),
iconImageView.heightAnchor.constraint(equalToConstant: 36),
closeButton.centerYAnchor.constraint(equalTo: bannerCard.centerYAnchor),
closeButton.trailingAnchor.constraint(equalTo: bannerCard.trailingAnchor, constant: -16),
closeButton.widthAnchor.constraint(equalToConstant: 28),
closeButton.heightAnchor.constraint(equalToConstant: 28),
titleLabel.centerYAnchor.constraint(equalTo: bannerCard.centerYAnchor),
titleLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, constant: 12),
titleLabel.trailingAnchor.constraint(equalTo: closeButton.leadingAnchor, constant: -12)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
3. SwiftUI Ekvivalenti
import SwiftUI
struct Task11SwiftUIView: View {
var body: some View {
HStack(spacing: 12) {
Image(systemName: "bell.badge.fill")
.font(.system(size: 20))
.foregroundColor(.blue)
.frame(width: 36, height: 36)
VStack(alignment: .leading, spacing: 4) {
Text("Yangi topshiriq tayyor")
.font(.system(size: 14, weight: .bold))
.foregroundColor(.white)
Text("SnapKit kursidan 20 ta amaliy vazifani boshlang.")
.font(.system(size: 11))
.foregroundColor(.gray)
.lineLimit(2)
}
Spacer()
Button(action: {}) {
Text("✕")
.font(.system(size: 13, weight: .bold))
.foregroundColor(.white)
.frame(width: 28, height: 28)
.background(Color(white: 0.25))
.clipShape(Circle())
}
}
.padding(16)
.frame(height: 80)
.background(Color(white: 0.15))
.clipShape(RoundedRectangle(cornerRadius: 14))
.padding(.horizontal, 16)
.padding(.top, 60)
.background(Color(white: 0.08).ignoresSafeArea())
}
}
💡 Pro Tip & Arxitektura siri: Matn maydonining o'ng tomonini qat'iy ravishda
closeButton.snp.leadingga bog'lang. Bu orqali xabar matni har qancha uzun bo'lsa ham yopish tugmasining ustiga chiqib ketmaydi.
</details>
🟠 Topshiriq 12: Do'kon Mahsulot Kartasi (Product Grid Card)
Daraja:
Qiyin (Hard)| Maqsad: Zamonaviy e-commerce kartasi: rasm, uning burchagidagi chegarma nishoni, sarlavha, narx va pastki o'ngdagi dumaloq qo'shish tugmasi ('+').
Murakkab vizual ierarxiya, elementlararo bog'lanish va nisbatlarni toza boshqarish.
Vizual Sxema (UI Mockup)
Topshiriq 12: Do'kon Mahsulot Kartasi (Product Grid Card)
📋 Texnik Talablar va Cheklovlar
- Karta: kengligi 220 pt, burchak radiusi 16 pt, fon to'q rangda.
- Mahsulot rasmi: kartaning yuqori qismida, balandligi 110 pt, ichki margin 12 pt.
- Chegarma nishoni (-25%): rasmining yuqori-chap burchagida 8 pt oraliqda.
- Title va Category rasmdan pastda.
- Pastda yashil narx ($249) va uning o'ng tomonida 36x36 o'lchamli dumaloq sariq '+' tugmasi.
<details> <summary>💡 Kodni ko'rish (SnapKit, UIKit va SwiftUI yechimlari)</summary>
1. SnapKit Yechimi (Asosiy)
import UIKit
import SnapKit