# SnapKit 17: UIKit + SwiftUI Interop — SnapKit bilan qurilgan UI ichida SwiftUI va aksincha

> **Holat:** 2026-yil oktabr. SwiftUI va UIKit aralashmasi — bu faqat vaqtinchalik o'tish davri emas, balki zamonaviy iOS dasturlashning ajralmas qismidir. Aksariyat yirik kompaniyalar millionlab qator UIKit (va SnapKit) legacy kodlariga ega, ammo yangi feature'larni SwiftUI yordamida yozishni xohlashadi. Shu bilan birga, SwiftUI yetishmovchiliklari sababli ba'zi qismlar hali ham UIKit bilan samaraliroq yoziladi. Professional iOS dasturchi har ikkala freymvorkni puxta bilishi va ularni birgalikda, uzluksiz ishlatishni uddalashi shart.

## Mundarija
1. [Nima uchun aralash ishlatamiz?](#why-mix)
2. [SwiftUI View'ni UIKit ichiga qo'yish — UIHostingController](#hosting-controller)
3. [Amaliy misol 1: UIKit ekran ichida SwiftUI chart](#example-chart)
4. [UIHostingConfiguration (iOS 16+) — Cell ichida SwiftUI](#hosting-config)
5. [Amaliy misol 2: SnapKit Settings ekran + SwiftUI toggle row](#example-settings)
6. [UIKit View'ni SwiftUI ichiga qo'yish — UIViewRepresentable](#view-representable)
7. [UIViewControllerRepresentable](#vc-representable)
8. [Amaliy misol 3: SwiftUI app ichida SnapKit-based custom view](#example-custom-view)
9. [Data Flow — UIKit ↔ SwiftUI sinxronlash](#data-flow)
10. [Amaliy misol 4: To'liq Hybrid App arxitekturasi](#hybrid-architecture)
11. [sizeThatFits va Layout](#size-that-fits)
12. [Performance va Best Practices](#best-practices)
13. [Anti-patterns (Qilmang!)](#anti-patterns)
14. [iOS 26 yangiliklari](#ios26)
15. [Xulosa](#xulosa)
16. [Manbalar](#manbalar)

---

## 1. Nima uchun aralash ishlatamiz? {#why-mix}

SwiftUI juda kuchli va tez, biroq hammasini ham o'z ichiga olmagan.

| UIKit (SnapKit) Afzalliklari | SwiftUI Afzalliklari |
| --- | --- |
| Murakkab animatsiyalar va custom gesture'lar qulay. | Declarative va reaktiv UI. |
| CollectionView'lar bilan maxsus layout'lar qilish qulay. | Prototip yaratish juda tez (Live Previews). |
| Katta va eski loyihalarda tayyor infratuzilma mavjud. | Yangi dizayn tizimlarini qisqa kod bilan yozish oson. |
| UI elementlar ustidan 100% past darajadagi nazorat. | Animatsiyalar oddiyroq va state'ga bog'langan. |

Hatto Apple ham o'zining ko'pgina ilovalarida (Settings, Maps, Music) UIKit hamda SwiftUI ni bitta ekran ichida aralash ishlatadi.

---

## 2. SwiftUI View'ni UIKit ichiga qo'yish — UIHostingController {#hosting-controller}

SwiftUI `View` ni UIKit olamiga olib kiruvchi asosiy "ko'prik" bu — `UIHostingController`. Bu xuddi oddiy `UIViewController` kabi ishlaydi, faqat uning `view` xususiyati sizning SwiftUI view'ingizni o'zida saqlaydi.

UIKit ierarxiyasiga UIHostingController'ni to'g'ri qo'shish tartibi quyidagicha (SnapKit bilan):

```swift
import UIKit
import SnapKit
import SwiftUI

class DashboardViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        
        // 1. SwiftUI View'ni tayyorlash
        let swiftUIView = Text("Salom, SwiftUI!")
            .font(.largeTitle)
            .padding()
            .background(Color.blue.cornerRadius(10))
            .foregroundColor(.white)
        
        // 2. UIHostingController yaratish
        let hostingController = UIHostingController(rootView: swiftUIView)
        
        // 3. Child View Controller sifatida qo'shish (Juda muhim!)
        addChild(hostingController)
        view.addSubview(hostingController.view)
        
        // 4. SnapKit yordamida joylashuvni belgilash
        hostingController.view.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.equalTo(250)
            make.height.equalTo(100)
        }
        
        // 5. Ota-onaga qo'shilganligini tasdiqlash
        hostingController.didMove(toParent: self)
    }
}
```

> **Muhim:** `addChild` → `addSubview` → `SnapKit constraints` → `didMove(toParent:)` tartibi hech qachon buzilmasligi kerak. Aks holda touch event'lar yoki lifecycle (viewWillAppear va boshqalar) to'g'ri ishlamaydi.

---

## 3. Amaliy misol 1: UIKit ekran ichida SwiftUI chart {#example-chart}

Zamonaviy ilovalarda diagrammalar (charts) kerak bo'lganda iOS 16 da chiqqan `Charts` framework juda qulay. Agar sizning asosingiz UIKit bo'lsa, uni shu tarzda joylaysiz:

```swift
import UIKit
import SnapKit
import SwiftUI
import Charts

// 1. SwiftUI Chart Component
struct WeeklySalesChart: View {
    var body: some View {
        Chart {
            BarMark(x: .value("Day", "Mon"), y: .value("Sales", 120))
            BarMark(x: .value("Day", "Tue"), y: .value("Sales", 200))
            BarMark(x: .value("Day", "Wed"), y: .value("Sales", 150))
            BarMark(x: .value("Day", "Thu"), y: .value("Sales", 250))
            BarMark(x: .value("Day", "Fri"), y: .value("Sales", 300))
        }
        .foregroundStyle(.blue.gradient)
    }
}

// 2. UIKit ViewController bilan SnapKit
class AnalyticsViewController: UIViewController {
    
    private let headerLabel: UILabel = {
        let lbl = UILabel()
        lbl.text = "Haftalik Savdolar"
        lbl.font = .boldSystemFont(ofSize: 24)
        return lbl
    }()
    
    private let chartContainer = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupChart()
    }
    
    private func setupUI() {
        view.backgroundColor = .systemGroupedBackground
        
        view.addSubview(headerLabel)
        view.addSubview(chartContainer)
        
        headerLabel.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
            make.leading.equalToSuperview().offset(20)
        }
        
        chartContainer.snp.makeConstraints { make in
            make.top.equalTo(headerLabel.snp.bottom).offset(20)
            make.leading.trailing.equalToSuperview().inset(20)
            make.height.equalTo(300)
        }
    }
    
    private func setupChart() {
        let chartVC = UIHostingController(rootView: WeeklySalesChart())
        chartVC.view.backgroundColor = .clear // Oq fon bo'lmasligi uchun
        
        addChild(chartVC)
        chartContainer.addSubview(chartVC.view)
        
        chartVC.view.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        chartVC.didMove(toParent: self)
    }
}
```

---

## 4. UIHostingConfiguration (iOS 16+) — Cell ichida SwiftUI {#hosting-config}

TableView yoki CollectionView cell'larini layout qilish SnapKit'da biroz zerikarli bo'lishi mumkin (ayniqsa murakkab state'lar bo'lsa). iOS 16 dan boshlab `UIHostingConfiguration` chiqdi. Bu API sizga cell'ning kontentini to'liq SwiftUI'da yozib, lekin jadvalni (`UITableView`) o'zini UIKit'da boshqarish imkonini beradi.

```swift
import UIKit
import SnapKit
import SwiftUI

// SwiftUI Cell View
struct UserCellView: View {
    let name: String
    let role: String
    
    var body: some View {
        HStack(spacing: 16) {
            Image(systemName: "person.circle.fill")
                .resizable()
                .frame(width: 50, height: 50)
                .foregroundColor(.blue)
            
            VStack(alignment: .leading, spacing: 4) {
                Text(name)
                    .font(.headline)
                Text(role)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
            Spacer()
            
            Image(systemName: "chevron.right")
                .foregroundColor(.gray)
        }
        .padding(.vertical, 8)
    }
}
```

Endi shuni `UITableView` ichida ishlatamiz:

```swift
class UsersListViewController: UIViewController, UITableViewDataSource {
    
    private let tableView = UITableView(frame: .zero, style: .insetGrouped)
    private let users = [("Ali", "Admin"), ("Vali", "Moderator"), ("Sami", "User")]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.dataSource = self
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        view.addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        let user = users[indexPath.row]
        
        // ✨ Mana haqiqiy sehr:
        cell.contentConfiguration = UIHostingConfiguration {
            UserCellView(name: user.0, role: user.1)
        }
        
        return cell
    }
}
```

> **Senior eslatmasi:** `UIHostingConfiguration` cell qayta ishlatilganda (reuse) juda yaxshi optimallashtirilgan. Oldingiday har bir cell uchun alohida `UIHostingController` yaratish shart emas va xotira sizib chiqishi (memory leak) xavfi ham kam.

---

## 5. Amaliy misol 2: SnapKit Settings ekran + SwiftUI toggle row {#example-settings}

Keling endi state (holat) o'zgarishini UIKit va SwiftUI o'rtasida bog'laymiz.

```swift
import UIKit
import SnapKit
import SwiftUI

// Shared ViewModel (Sinxronlash uchun)
class SettingsViewModel: ObservableObject {
    @Published var isDarkModeEnabled: Bool = false
    @Published var notificationsEnabled: Bool = true
}

// SwiftUI Toggle Row
struct SettingsToggleRow: View {
    let title: String
    let icon: String
    @Binding var isOn: Bool
    
    var body: some View {
        HStack {
            Image(systemName: icon)
                .foregroundColor(.white)
                .padding(6)
                .background(Color.blue.cornerRadius(8))
            
            Toggle(title, isOn: $isOn)
        }
    }
}

// UIKit Controller
class AppSettingsViewController: UIViewController, UITableViewDataSource {
    
    private let tableView = UITableView(frame: .zero, style: .insetGrouped)
    private var viewModel = SettingsViewModel() // State source of truth
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Settings"
        
        view.addSubview(tableView)
        tableView.dataSource = self
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        if indexPath.row == 0 {
            cell.contentConfiguration = UIHostingConfiguration {
                // SwiftUI state UIKit ViewModel ga Binding orqali uzatilyapti
                SettingsToggleRow(
                    title: "Dark Mode",
                    icon: "moon.fill",
                    isOn: Binding(
                        get: { self.viewModel.isDarkModeEnabled },
                        set: { self.viewModel.isDarkModeEnabled = $0 }
                    )
                )
            }
        } else {
            cell.contentConfiguration = UIHostingConfiguration {
                SettingsToggleRow(
                    title: "Notifications",
                    icon: "bell.fill",
                    isOn: Binding(
                        get: { self.viewModel.notificationsEnabled },
                        set: { self.viewModel.notificationsEnabled = $0 }
                    )
                )
            }
        }
        
        return cell
    }
}
```

---

## 6. UIKit View'ni SwiftUI ichiga qo'yish — UIViewRepresentable {#view-representable}

Endi tangani ikkinchi tarafiga qaraymiz. Sizda faqat SwiftUI loyiha bor, lekin siz eskidan yozib qo'ygan SnapKit orqali yozilgan kuchli `CustomCardView` ni ishlatmoqchisiz. Buning uchun `UIViewRepresentable` protokoli yordamga keladi.

```swift
import SwiftUI
import UIKit
import SnapKit

// 1. Bizning UIKit (SnapKit) bilan yozilgan custom view'imiz
class CustomCardView: UIView {
    
    private let titleLabel = UILabel()
    private let subtitleLabel = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
    
    private func setupViews() {
        backgroundColor = .systemTeal
        layer.cornerRadius = 16
        
        titleLabel.font = .boldSystemFont(ofSize: 20)
        titleLabel.textColor = .white
        
        subtitleLabel.font = .systemFont(ofSize: 14)
        subtitleLabel.textColor = .white.withAlphaComponent(0.8)
        
        addSubview(titleLabel)
        addSubview(subtitleLabel)
        
        titleLabel.snp.makeConstraints { make in
            make.top.leading.equalToSuperview().offset(16)
            make.trailing.equalToSuperview().offset(-16)
        }
        
        subtitleLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(8)
            make.leading.trailing.equalTo(titleLabel)
            make.bottom.lessThanOrEqualToSuperview().offset(-16)
        }
    }
    
    func configure(title: String, subtitle: String) {
        titleLabel.text = title
        subtitleLabel.text = subtitle
    }
}

// 2. SwiftUI Wrapper
struct SnapKitCardView: UIViewRepresentable {
    
    var title: String
    var subtitle: String
    
    // a. UIView ni yaratish
    func makeUIView(context: Context) -> CustomCardView {
        let view = CustomCardView()
        // MUHIM: SnapKit constraint'lar shu yerda EMAS, balki UIView o'zining initida qilingani ma'qul.
        return view
    }
    
    // b. SwiftUI state o'zgarganda UIView ni yangilash
    func updateUIView(_ uiView: CustomCardView, context: Context) {
        uiView.configure(title: title, subtitle: subtitle)
    }
}
```

---

## 7. UIViewControllerRepresentable {#vc-representable}

Agar siz bitta UIView'ni emas, butun bir UIViewController'ni SwiftUI ichiga olib kirmoqchi bo'lsangiz `UIViewControllerRepresentable` kerak bo'ladi. Bu ko'pincha tizimning tayyor kontrollerlari (`UIImagePickerController`, `SFSafariViewController`) yoki o'zingizning to'liq SnapKit arxitekturangizni chaqirish uchun ishlatiladi.

```swift
import SwiftUI
import UIKit

struct ImagePickerWrapper: UIViewControllerRepresentable {
    
    @Binding var selectedImage: UIImage?
    @Environment(\.presentationMode) var presentationMode
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator // Delegate handling
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
        // Yangilanishlar shu yerda
    }
    
    // Delegate event'larini SwiftUI olamiga uzatish uchun Coordinator
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        var parent: ImagePickerWrapper
        
        init(_ parent: ImagePickerWrapper) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[.originalImage] as? UIImage {
                parent.selectedImage = image
            }
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}
```

---

## 8. Amaliy misol 3: SwiftUI app ichida SnapKit-based custom view {#example-custom-view}

Endi yuqorida yasagan `SnapKitCardView` imizni haqiqiy SwiftUI Content View ichida qo'llaymiz.

```swift
import SwiftUI

struct HomeContentView: View {
    @State private var cardTitle = "SnapKit Card"
    @State private var counter = 0
    
    var body: some View {
        VStack(spacing: 30) {
            Text("SwiftUI App Asosi")
                .font(.largeTitle)
                .bold()
            
            // UIKit (SnapKit) Custom View shu yerda yotibdi
            SnapKitCardView(
                title: cardTitle,
                subtitle: "Ushbu karta to'liq SnapKit'da yozilgan. Bosilgan: \(counter) marta."
            )
            .frame(height: 120)
            .padding(.horizontal)
            
            Button("Karta ma'lumotini yangilash") {
                counter += 1
                cardTitle = "Yangilandi! 🔥"
            }
            .buttonStyle(.borderedProminent)
            
            Spacer()
        }
        .padding(.top)
    }
}
```

Kodni e'tibor bilan kuzatsangiz: SwiftUI Button bosilganda @State o'zgaradi -> `updateUIView` avtomatik ishlaydi -> SnapKit View dagi yozuv darhol o'zgaradi!

---

## 9. Data Flow — UIKit ↔ SwiftUI sinxronlash {#data-flow}

Ma'lumotlar oqimini ikki olam o'rtasida to'g'ri tashkil qilish juda muhim:

- **UIKit → SwiftUI**: `@ObservableObject` (yoki yangi Swift 6/iOS 17+ larda `@Observable` macro) class yarating. Uni o'zgartirsangiz SwiftUI avtomatik yangilanadi. Yoki `UIHostingController`ning root view xususiyatlarini yangilash mumkin.
- **SwiftUI → UIKit**: Custom `delegate` yoki block klosure'larni ishlatish eng qulay. Yoki `@Binding` ishlatib SwiftUI state'ini `updateUIView` orqali UIkit'ga push qilasiz.

---

## 10. Amaliy misol 4: To'liq Hybrid App arxitekturasi {#hybrid-architecture}

Quyida bitta dastur ichida UIKit TabBar bilan SwiftUI va SnapKit interfeyslari mukammal aralashib ishlagan keng qamrovli misol.

```swift
import UIKit
import SwiftUI
import SnapKit

// Shared Model
@Observable
class AppState {
    var globalCounter = 0
}

// ==========================================
// Tab 1: UIKit + SnapKit + SwiftUI Embed
// ==========================================
class FirstTabViewController: UIViewController {
    let appState: AppState
    
    init(state: AppState) {
        self.appState = state
        super.init(nibName: nil, bundle: nil)
        title = "Hybrid Home"
        tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0)
    }
    required init?(coder: NSCoder) { fatalError() }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        
        // SwiftUI Counter Widget ni UIKit ichiga o'rnatamiz
        let widget = CounterSwiftUIView(state: appState)
        let hostingController = UIHostingController(rootView: widget)
        
        addChild(hostingController)
        view.addSubview(hostingController.view)
        
        hostingController.view.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        hostingController.didMove(toParent: self)
    }
}

// SwiftUI Widget
struct CounterSwiftUIView: View {
    var state: AppState
    
    var body: some View {
        VStack {
            Text("SwiftUI Widget")
                .font(.headline)
            Text("Global Counter: \(state.globalCounter)")
            Button("Oshirish") {
                state.globalCounter += 1
            }
            .padding()
            .background(Color.green)
            .foregroundColor(.white)
            .cornerRadius(10)
        }
    }
}

// ==========================================
// Asosiy TabBarController (Entry Point)
// ==========================================
@MainActor
class MainTabBarController: UITabBarController {
    
    let sharedState = AppState()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let tab1 = FirstTabViewController(state: sharedState)
        let tab1Nav = UINavigationController(rootViewController: tab1)
        
        // Tab 2: To'liq SwiftUI View ni HostingController orqali TabBar'ga tiqish
        let tab2View = SettingsSwiftUIView(state: sharedState)
        let tab2VC = UIHostingController(rootView: tab2View)
        tab2VC.title = "SwiftUI Settings"
        tab2VC.tabBarItem = UITabBarItem(title: "Settings", image: UIImage(systemName: "gear"), tag: 1)
        
        self.viewControllers = [tab1Nav, tab2VC]
    }
}

struct SettingsSwiftUIView: View {
    var state: AppState
    
    var body: some View {
        Form {
            Section(header: Text("App State Info")) {
                Text("Current Counter: \(state.globalCounter)")
                Button("Nolga tushirish (Reset)") {
                    state.globalCounter = 0
                }
            }
        }
    }
}
```

Bu kod 2026-yilda yirik kompaniyalarda (masalan, Yandex yoki Telegram'ning yangi modullarida) ko'p uchraydigan naqsh (pattern) hisoblanadi.

---

## 11. sizeThatFits va Layout {#size-that-fits}

Eng ko'p qilinadigan xato — SwiftUI content o'lchami o'zgarganda UIKit `UIHostingController.view` o'lchamini bilmay qolishi.
Agar siz SwiftUI View'ning o'ziga xos aniq o'lchamini (intrinsic size) olmoqchi bo'lsangiz:

```swift
let hostingView = hostingController.view!
// AutoresizingMask o'chirilgan bo'lishi shart
hostingView.translatesAutoresizingMaskIntoConstraints = false 

// SwiftUI o'zini eng optimal o'lchamini hisoblaydi
let fittingSize = hostingController.sizeThatFits(in: CGSize(width: view.bounds.width, height: UIView.layoutFittingExpandedSize.height))

hostingView.snp.makeConstraints { make in
    make.width.equalTo(fittingSize.width)
    make.height.equalTo(fittingSize.height)
}

// Keyinchalik SwiftUI state o'zgarsa, UI ni qayta chizish uchun:
hostingView.invalidateIntrinsicContentSize()
```

---

## 12. Performance va Best Practices {#best-practices}

1. **#Preview (iOS 17+) UIKit va SnapKit uchun:**
SnapKit bilan yozilgan UIKit kodingizni tekshirish uchun simulyatorni har safar yurgizish shart emas. Yangi Makro tizimi orqali uni to'g'ridan to'g'ri Xcode Previews da ko'rishingiz mumkin:

```swift
#Preview("SnapKit Card View") {
    let view = CustomCardView()
    view.configure(title: "Preview Test", subtitle: "Working perfectly")
    return view
}
```

2. **UIHostingController og'irligi:** U xotira uchun unchalik "qimmat" emas, lekin cell'lar ichida har safar `new UIHostingController()` yaratish sekinlashtiradi. Buning o'rniga iOS 16 dan beri tavsiya qilingan `UIHostingConfiguration` ni ishlating.

---

## 13. Anti-patterns (Qilmang!) {#anti-patterns}

| Yomon tajriba (Anti-pattern) | Nima sababdan? | Yechim |
| --- | --- | --- |
| `makeUIView` ichida `.snp.makeConstraints` yozish. | SwiftUI uni qayta-qayta chaqirishi mumkin, duplicate constraints vujudga keladi. | Constraint'larni faqat UIView'ning `init()` metodida 1 marta qiling. |
| UIKit background thread'dan `@State` yoki `@Published` ni o'zgartirish. | SwiftUI state'lari faqatgina Main Thread'da xavfsiz o'zgarishi kerak. | Doim `@MainActor` yoki `DispatchQueue.main.async` ishlating. |
| UIHostingController.view ga `translatesAutoresizingMaskIntoConstraints = true` qoldirish. | SnapKit constraint'lari UIKit autoresizing mask bilan urishib, ziddiyat (Conflict) beradi. | SnapKit `snp.makeConstraints` o'zi avtomatik buni `false` qiladi, qo'lda true ga o'zgartirmang! |

---

## 14. iOS 26 yangiliklari (2026-yil holatiga) {#ios26}

2026-yilga kelib SwiftUI va UIKit orasidagi chegara deyarli yo'qolgan. Yangi `UIHostingConfiguration` API'larida `Liquid Glass` va `Depth Modifiers` to'g'ridan-to'g'ri UIKit view'laridan o'qilishi qo'shilgan.
Endi siz UIKit ichida animatsiyalarni boshqarib, uni SwiftUI `withAnimation` bloki ichida uzluksiz tutishingiz mumkin. Bu SnapKit arxitekturasi bilan ishlaydigan har bir iOS dasturchi uchun ulkan erkinlik beradi.

---

## Xulosa {#xulosa}

Zamonaviy iOS dasturchi "Men faqat SwiftUI da yozaman" yoki "UIKit dan boshqasi bekor" deb aytishga haqli emas. 2026-yilda mukammal ilovalar yaratish — bu to'g'ri joyda to'g'ri asbobni tanlay bilish san'atidir. Murakkab formalar, oddiy holat (state) boshqaruvi uchun SwiftUI ni ishlatsangiz, murakkab layout, past darajali optimizatsiya va katta arxitekturalar uchun SnapKit yordamida UIKit dan foydalanish eng to'g'ri tanlovdir.

---

## Manbalar {#manbalar}

- [Apple Documentation: Interfacing with UIKit](https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)
- [WWDC22: Use SwiftUI with UIKit](https://developer.apple.com/videos/play/wwdc2022/10072/)
- [SnapKit Rasmiy hujjatlari](https://snapkit.github.io/SnapKit/docs/)
- [SwiftUI View Lifecycle and UIKit](https://developer.apple.com/documentation/swiftui/uiviewrepresentable)
