UIKit
Cheat Sheet'lar
UIKit Cheat Sheet
iOS dasturlashda UIKit frameworki orqali imperativ interfeyslar, View Lifecycle va Auto Layout bilan ishlash bo'yicha tezkor qo'llanma.
1. UIViewController Lifecycle (Hayotiy sikli)
| Metod | Qachon chaqiriladi? | Nima qilish kerak? |
|---|---|---|
loadView() | View xotiraga yuklanganda (faqat custom view o'rnatishda override qilinadi) | self.view = CustomView() |
viewDidLoad() | View xotiraga bir marta yuklanganda | UI elementlarni qo'shish, constraintlar, dastlabki API so'rov |
viewWillAppear(_:) | Ekran foydalanuvchiga ko'rinishidan oldin (har safar) | UI yangilash, navigatsiya barini sozlash, klaviatura obunasi |
viewWillLayoutSubviews() | View'ning frame'lari o'lchanishidan oldin | Layout o'zgarishlariga tayyorgarlik |
viewDidLayoutSubviews() | Auto Layout subview'lar o'lchamini hisoblab bo'lganda | Gradient layer frame'larini yangilash, cornerRadius |
viewDidAppear(_:) | Ekran to'liq ko'ringanda | Animatsiyalarni boshlash, video ijro etish, analitika yuborish |
viewWillDisappear(_:) | Ekran yopilishidan oldin | Klaviaturani tushirish, taymerlarni to'xtatish |
viewDidDisappear(_:) | Ekran butunlay yashiringanda | Og'ir resurslarni pauza qilish |
deinit | Controller xotiradan tozalanayotganda | Retain cycle tekshirish, observerlarni tozalash |
2. Programmatic UI & Auto Layout
Auto Layout kodda yozilganda har doim translatesAutoresizingMaskIntoConstraints = false bo'lishi shart!
final class ProfileHeaderView: UIView {
private let avatarImageView: UIImageView = {
let iv = UIImageView()
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 32
iv.backgroundColor = .systemGray5
return iv
}()
private let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = .systemFont(ofSize: 18, weight: .bold)
label.textColor = .label
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupLayout()
}
required init?(coder: NSCoder) { fatalError("init(coder:) unhandled") }
private func setupLayout() {
addSubview(avatarImageView)
addSubview(titleLabel)
NSLayoutConstraint.activate([
// Avatar
avatarImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
avatarImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
avatarImageView.widthAnchor.constraint(equalToConstant: 64),
avatarImageView.heightAnchor.constraint(equalToConstant: 64),
// Title
titleLabel.leadingAnchor.constraint(equalTo: avatarImageView.trailingAnchor, constant: 12),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
titleLabel.centerYAnchor.constraint(equalTo: avatarImageView.centerYAnchor)
])
}
}
Content Hugging & Compression Resistance:
- Hugging (Kengayishga qarshilik): Element o'z matnidan katta bo'lib ketmasin.
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
- Compression Resistance (Siqilishga qarshilik): Matn qisqarib (
...) ketmasin.
label.setContentCompressionResistancePriority(.required, for: .horizontal)
3. UIStackView
Kodda elementlarni chiroyli joylashtirishning eng qulay usuli.
let stack = UIStackView(arrangedSubviews: [nameLabel, descLabel])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .vertical // .horizontal yoki .vertical
stack.spacing = 8
stack.alignment = .fill // .leading, .trailing, .center, .fill
stack.distribution = .fillProportionally // .fillEqually, .equalSpacing
4. Modern UICollectionView & DiffableDataSource
iOS 14+ da zamonaviy List/Grid yaratish usuli (Delegatesiz va crash'larsiz).
// 1. Model
struct Item: Hashable {
let id = UUID()
let title: String
}
enum Section { case main }
// 2. ViewController ichida
final class ItemsViewController: UIViewController {
private var collectionView: UICollectionView!
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
override func viewDidLoad() {
super.viewDidLoad()
configureHierarchy()
configureDataSource()
applyInitialData()
}
private func configureHierarchy() {
// iOS 14+ List Configuration
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
let layout = UICollectionViewCompositionalLayout.list(using: config)
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(collectionView)
}
private func configureDataSource() {
// Cell Registration
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { cell, indexPath, item in
var content = cell.defaultContentConfiguration()
content.text = item.title
content.image = UIImage(systemName: "star")
cell.contentConfiguration = content
}
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item)
}
}
private func applyInitialData() {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems([Item(title: "Swift"), Item(title: "UIKit"), Item(title: "SwiftUI")])
dataSource.apply(snapshot, animatingDifferences: true)
}
}
5. Delegation & Target-Action
Delegate Pattern:
protocol CustomButtonDelegate: AnyObject {
func didTapActionButton(_ sender: CustomButton)
}
final class CustomButton: UIView {
weak var delegate: CustomButtonDelegate? // weak shart!
private func handleTap() {
delegate?.didTapActionButton(self)
}
}
Target-Action:
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
@objc private func buttonTapped() {
print("Tugma bosildi")
}
6. Navigatsiya va Modallar (Navigation & Modals)
// 1. Push (NavigationController ichida)
let detailVC = DetailViewController()
navigationController?.pushViewController(detailVC, animated: true)
// Pop (Orqaga)
navigationController?.popViewController(animated: true)
// 2. Modal Present
let modalVC = SheetViewController()
modalVC.modalPresentationStyle = .pageSheet // yoki .fullScreen, .formSheet
if let sheet = modalVC.sheetPresentationController {
sheet.detents = [.medium(), .large()]
sheet.prefersGrabberVisible = true
}
present(modalVC, animated: true)
// Dismiss
dismiss(animated: true)
7. Alerts & ActionSheet
let alert = UIAlertController(title: "O'chirish", message: "Ishonchingiz komilmi?", preferredStyle: .alert)
let deleteAction = UIAlertAction(title: "Ha, o'chir", style: .destructive) { _ in
// Delete logikasi
}
let cancelAction = UIAlertAction(title: "Bekor qilish", style: .cancel)
alert.addAction(deleteAction)
alert.addAction(cancelAction)
present(alert, animated: true)
8. UIView Animatsiyalari
// Oddiy animatsiya
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseInOut]) {
self.cardView.alpha = 1.0
self.cardView.transform = .identity
}
// Spring Animatsiya (Sakrash effekti)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5) {
self.button.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
}
// Interaktiv Animator (UIViewPropertyAnimator)
let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeOut) {
self.view.backgroundColor = .systemRed
}
animator.startAnimation()
9. Gestures (Harakatlar)
let tap = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:)))
tap.numberOfTapsRequired = 1
containerView.addGestureRecognizer(tap)
containerView.isUserInteractionEnabled = true // Majburiy!
@objc private func viewTapped(_ gesture: UITapGestureRecognizer) {
print("Bosildi:", gesture.location(in: view))
}