Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 클린 코드
- SWIFT
- 리펙토링
- HIG
- Protocol
- RxCocoa
- 리펙터링
- swiftUI
- map
- ios
- 리팩토링
- tableView
- swift documentation
- ribs
- Human interface guide
- 애니메이션
- UITextView
- rxswift
- combine
- Clean Code
- uiscrollview
- uitableview
- 스위프트
- UICollectionView
- Xcode
- Observable
- clean architecture
- collectionview
- Refactoring
- MVVM
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] 튜토리얼 - 13. SwiftUI에서 UIKit 사용 방법 (UIViewRepresentable, UIViewControllerRepresentable) 본문
iOS 튜토리얼 (SwiftUI)
[iOS - SwiftUI] 튜토리얼 - 13. SwiftUI에서 UIKit 사용 방법 (UIViewRepresentable, UIViewControllerRepresentable)
jake-kim 2022. 7. 15. 22:23SwiftUI에서 UIkit 사용 방법 - UIView
- UIViewRepresentable 프로토콜을 구현하면 SwiftUI에서 UIView 사용 가능
@available(iOS 13.0, tvOS 13.0, *)
@available(macOS, unavailable)
@available(watchOS, unavailable)
public protocol UIViewRepresentable : View where Self.Body == Never {
associatedtype UIViewType : UIView
func makeUIView(context: Self.Context) -> Self.UIViewType
func updateUIView(_ uiView: Self.UIViewType, context: Self.Context)
static func dismantleUIView(_ uiView: Self.UIViewType, coordinator: Self.Coordinator)
associatedtype Coordinator = Void
func makeCoordinator() -> Self.Coordinator
typealias Context = UIViewRepresentableContext<Self>
}
- UIViewControllerRepresentable의 3가지를 필수로 정의하여 사용
- makeUIView(context:) -> Self.UIViewType: UIView를 생성하고 초기화
- updateUIView(_:,context:): UIView 업데이트가 필요할 때 호출하는 메소드
ex) UIViewRepresentable를 이용하여 SwiftUI에서 UILabel 사용방법
- UIViewRepresentable 프로토콜을 구현
- makeUIView메소드와 updateUIView를 구현
struct MyUILabel: UIViewRepresentable {
@Binding var text: String // @Bidning property: SwiftUI -> UIKit으로의 데이터 전달
func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.textColor = .blue
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
uiView.text = text
}
}
- 사용할 땐 SwiftUI 사용하는 방법대로 그대로 사용
import UIKit
import SwiftUI
struct ContentView: View {
@State var text: String
var body: some View {
VStack {
MyUILabel(text: $text)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(text: "Example Text")
}
}
Coordinator 개념
- UIViewRepresentable에서 Coordinator 타입과 makeCoordinator()이 존재
- Coordinator는 UIKit -> SwiftUI로의 데이터 전달 (= delegate 역할)
- @Bidning property는 SwiftUI -> UIkit으로의 데이터 전달
- UITableView에서의 UITableViewDataSource, UITableViewDelegate이 Coordinator와 동일한 역할
ex) UITableView에서 delegate까지 구현 방법
- updateUIView(_:context:)에서, context로 Coordinator 인스턴스에 접근하여 델리게이트 할당
import UIKit
import SwiftUI
struct MyTableView: UIViewRepresentable {
@Binding var isShowing: Bool
func makeUIView(context: Context) -> UITableView {
UITableView()
}
func updateUIView(_ uiView: UITableView, context: Context) {
guard self.isShowing else { return }
uiView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
uiView.delegate = context.coordinator // <-
uiView.dataSource = context.coordinator // <-
}
}
- Coordinator에 delegate를 할당하고, makeCoordinator()의 반환값을 Coordinator 인스턴스로 반환
import UIKit
import SwiftUI
struct MyTableView: UIViewRepresentable {
@Binding var isShowing: Bool
func makeUIView(context: Context) -> UITableView {
UITableView()
}
func updateUIView(_ uiView: UITableView, context: Context) {
guard self.isShowing else { return }
uiView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
uiView.delegate = context.coordinator
uiView.dataSource = context.coordinator
}
func makeCoordinator() -> Coordinator { // <-
Coordinator()
}
class Coordinator: NSObject, UITableViewDelegate, UITableViewDataSource { // <-
var dataSource = (0...10).map(String.init(_:))
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = self.dataSource[indexPath.row]
return cell
}
}
}
SwiftUI에서 UIkit 사용 방법 - UIViewController
- UIViewControllerRepresentable 프로토콜을 구현하면 SwiftUI에서 UIViewController 사용 가능
@available(iOS 13.0, tvOS 13.0, *)
@available(macOS, unavailable)
@available(watchOS, unavailable)
public protocol UIViewControllerRepresentable : View where Self.Body == Never {
associatedtype UIViewControllerType : UIViewController
func makeUIViewController(context: Self.Context) -> Self.UIViewControllerType
func updateUIViewController(_ uiViewController: Self.UIViewControllerType, context: Self.Context)
static func dismantleUIViewController(_ uiViewController: Self.UIViewControllerType, coordinator: Self.Coordinator)
associatedtype Coordinator = Void
func makeCoordinator() -> Self.Coordinator
typealias Context = UIViewControllerRepresentableContext<Self>
}
- UIView를 사용할때와 마찬가지로, UIViewControllerRepresentable의 2가지를 필수로 정의하여 사용
- makeUIViewController(context:): UIViewController를 생성하고 초기화
- updateUIViewController(_:context:): ViewController 업데이트가 필요할 때 호출되는 메소드 (ViewController에 필요한 데이터를 갱신)
- Coordinator역시도 UIView에서 사용할때와 동일
* 전체 코드: https://github.com/JK0369/ExUIKit
* 참고
https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit
https://developer.apple.com/documentation/swiftui/uiviewcontrollerrepresentable
'iOS 튜토리얼 (SwiftUI)' 카테고리의 다른 글
Comments