- Published on
SwiftUI'da UIKit ekranlarini ishlatish (UIViewControllerRepresentable)
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Nima uchun ViewController kerak?
Oldingi darsda biz bitta oddiy UITextField ni UIViewRepresentable yordamida SwiftUI ga o'tkazgandik. Lekin ba'zida bizga tayyor to'liq oyna (ekran) kerak bo'lib qoladi. Eng yaxshi misol — Kamera yoki Rasmlar galereyasi (UIImagePickerController). Hali ham ko'p dasturchilar rasmlarni tanlash uchun UIKit'ning ushbu ochiq va moslashuvchan Controller'idan foydalanishadi.
Uni SwiftUI ga olib kirish uchun biz UIViewControllerRepresentable dan foydalanamiz.
1. Oddiy view controller yaratish
Avval eng sodda holatni ko'raylik. O'zimiz custom yasagan yoki tayyor UIViewController ni SwiftUI'da .sheet yoki NavigationLink yordamida ochmoqchimiz.
import SwiftUI
struct BasicUIViewControllerRepresentable: UIViewControllerRepresentable {
let labelText: String
// 1. Controller'ni yaratamiz
func makeUIViewController(context: Context) -> UIViewController {
let vc = UIViewController()
vc.view.backgroundColor = .blue
// Ekranga bitta yozuv qo'shamiz
let label = UILabel()
label.text = labelText
label.textColor = .white
label.frame = vc.view.frame
vc.view.addSubview(label)
return vc
}
// 2. SwiftUI dagi o'zgarishlarga qarab uni yangilaymiz
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
// Hozircha bo'sh
}
}
Buni istalgan SwiftUI tugmasi orqali ochish mumkin:
Button("Oynani ochish") {
showScreen.toggle()
}
.sheet(isPresented: $showScreen) {
BasicUIViewControllerRepresentable(labelText: "Yangi UIKit Oynasi!")
}
2. Rasmlar Galereyasini (UIImagePickerController) ulash
Haqiqiy muammo biz UIKit dagi galereyani ochib, u yerdan tanlangan rasmni SwiftUI ga qaytarib olmoqchi bo'lganimizda boshlanadi. Buning uchun biz yana Coordinator (Vositachi) dan foydalanamiz.
struct UIImagePickerControllerRepresentable: UIViewControllerRepresentable {
@Binding var image: UIImage?
@Binding var showScreen: Bool
func makeUIViewController(context: Context) -> UIImagePickerController {
let vc = UIImagePickerController()
vc.allowsEditing = false
// Vositachini tayinlaymiz!
vc.delegate = context.coordinator
return vc
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
// Vositachini yaratish
func makeCoordinator() -> Coordinator {
return Coordinator(image: $image, showScreen: $showScreen)
}
// Delegate metodlarini ushlaydigan Coordinator Class
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@Binding var image: UIImage?
@Binding var showScreen: Bool
init(image: Binding<UIImage?>, showScreen: Binding<Bool>) {
self._image = image
self._showScreen = showScreen
}
// Rasm tanlanganda avtomat ishlaydi
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// Tanlangan rasmni olamiz
if let newImage = info[.originalImage] as? UIImage {
self.image = newImage // Uni SwiftUI ga beramiz
}
// Va galereyani yopamiz
self.showScreen = false
}
}
}
Qanday foydalaniladi?
Endi SwiftUI sahifamizda bitta @State rasm obyekti yaratamiz va galereya qaytargan rasmni shu yerda ko'rsatamiz:
struct ImagePickerBootcamp: View {
@State private var showScreen: Bool = false
@State private var selectedImage: UIImage? = nil
var body: some View {
VStack {
if let image = selectedImage {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
Button("Rasm tanlash") {
showScreen.toggle()
}
}
.sheet(isPresented: $showScreen) {
UIImagePickerControllerRepresentable(image: $selectedImage, showScreen: $showScreen)
}
}
}
Xulosa: SwiftUI dagi ilovangizda tayyor UIKit imkoniyatlaridan (Kamera, Fayllar, Xaritalar) to'liq foydalanish imkoniyatini UIViewControllerRepresentable orqali hech qanday qiyinchiliksiz qila olasiz. Coordinator tushunchasi esa ular o'rtasida ishonchli ko'prik vazifasini o'taydi.