# 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!

```swift
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.
  ```swift
  label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
  ```
- **Compression Resistance (Siqilishga qarshilik)**: Matn qisqarib (`...`) ketmasin.
  ```swift
  label.setContentCompressionResistancePriority(.required, for: .horizontal)
  ```

---

## 3. UIStackView

Kodda elementlarni chiroyli joylashtirishning eng qulay usuli.

```swift
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).

```swift
// 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:
```swift
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:
```swift
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

@objc private func buttonTapped() {
    print("Tugma bosildi")
}
```

---

## 6. Navigatsiya va Modallar (Navigation & Modals)

```swift
// 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

```swift
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

```swift
// 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)

```swift
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))
}
```
