protocol UIViewRepresentable : View where Self.Body == Never
- UIView๊ฐ์ฒด๋ฅผ SwiftUI ์ธํฐํ์ด์ค์์ ๊ด๋ฆฌํ๊ณ ์์ฑํ ์ ์๊ฒ ํด์ค
- SwiftUI์์์ View์ ๋์ผํ๊ฒ ์์ฑ๋๊ณ ์ ๋ฐ์ดํธ ๋จ
- ์์คํ ์ UIViewRepresentable์ ์ฑํํ๋ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ ์ ํ ํ์ด๋ฐ์ ํธ์ถํจ
- ์์คํ ์ ํด๋น ๊ฐ์ฒด์ ๋ณํ์ ๋ํด ๋ค๋ฅธ View์ ์๋์ผ๋ก ์ํธ์์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ์ํ๋ ๊ฒฝ์ฐ Coordinator์ ์ฌ์ฉํด์ผ ํจ (target-action, delegate message ๋ฑ)
makeUIView
@MainActor
func makeUIView(context: Self.Context) -> Self.UIViewType
- View ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ด๊ธฐํ
- context parameter
- UIViewRepresentableContext<Self> ํ์ ์ผ๋ก์ ๋ง์ฝ WKWebView๋ฅผ UIViewPresentable์ ์ด์ฉํด CustomWebView๋ฅผ ๊ตฌํํ๋ค๋ฉด context์ ํ์ ์ UIViewRepresentableContext<CustomWebView>
- context์ ๊ฐ
- coordinator
- UIViewPresentable์ ์ํ ๋ฐ ์ด๋ฒคํธ ๊ด๋ฆฌ๋ฅผ ์ํด ์ฌ์ฉํ ์ ์์
- UIKit์ delegate ์ SwiftUI๋ฅผ ์ฐ๊ฒฐํ๋ ์ญํ
- environment
- ์ฌ์ฉ์๊ฐ ์ค์ ํ ํ๊ฒฝ ๊ฐ์ ๊ฐ์ง๊ณ ์์ ์ ์ฉํ ์ ์์
- context.environment.local : ๋ ์ง๋ ์ซ์ ํ์ ๋ก์ปฌ๋ผ์ด์ง์ ์ํด ์ฌ์ฉํ ์ ์์
- context.environment.colorScheme : ๋คํฌ๋ชจ๋์ธ์ง ๋ผ์ดํธ๋ชจ๋์ธ์ง ํ์ฌ ๊ธฐ๊ธฐ ์ค์ ๊ฐ์ ๊ฐ์ง๊ณ ์ฌ ์ ์์
- context.environment.accessibilityDifferentiateWithoutColor : ๋ํ ํ ์คํธ ์ค์ ์ด ๋์ด ์๋์ง ํ์ธํ๊ณ view์ ๊ฐ์ ์กฐ์ ํ๋๋ฐ ์ฌ์ฉํ ์ ์์
- transaction
- UIView ์ ๋๋ฉ์ด์ ๊ณผ SwiftUI์ ์ ๋๋ฉ์ด์ ์ ๋๊ธฐํ ํ ์ ์์
- SwiftUI์ ํ์ฌ ๋ทฐ ์ ๋ฐ์ดํธ ์ ๋ณด ํฌํจ
- ์ ๋๋ฉ์ด์ ๊ณผ ํธ๋์ ์ ์ฌ์ฉ๊ฐ๋ฅ
- coordinator
- ๋ฐํ๊ฐ์ด UIView ์ด๋ฉฐ ์ด๋ฅผ SwiftUI์ View์ ํ์ํจ. View๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ํ์๋ก ๊ตฌํ๋์ด์ผ ํ๋ ๋ฉ์๋
- ์ต์ด๋ก ๋ทฐ๊ฐ ํ๋ฒ ์์ฑ๋ ๋ ํ๋ฒ ํธ์ถ๋๋ ํจ์ (์ด๊ธฐ ์ค์ ). ํ๋ฉด์ด ๋ํ๋ ์ํ์์ ์ ๋ฐ์ดํธ๊ฐ ํ์ํ ๊ฒฝ์ฐ ๋ค๋ฅธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๊ตฌํํด์ผ ํจ
- ์ง์ ์ฌ์ฉํด ๋ณด๋ updateUIView๊ฐ ์๊ฐ๋ณด๋ค ์์ฃผ ํธ์ถ ๋์ด ์ ๋ฐ์ดํธ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. SwiftUI์์ ๋ทฐ ๊ณ์ธต์ด ์ ๋ฐ์ดํธ ๋๋ฉด updateUIView๋ ๊ฐ์ด ์ ๋ฐ์ดํธ ๋๊ธฐ ๋๋ฌธ์ ์ฃผ์ ํด์ผ ํจ
func makeUIView(context: Context) -> WKWebView {
print("makeUIView")
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
return webView
}
updateUIView
@MainActor
func updateUIView(
_ uiView: Self.UIViewType,
context: Self.Context
)
- SwiftUI์ View ์ฌ์ด์์ ์ ๋ฐ์ดํธ๊ฐ ํ์ํ ๋ ํธ์ถ. SwiftUI์ state๋ binding, ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ UIKit์ ๋ฐ์
- uiView๋ UIViewRepresentable์ ์ฑํํ Custom View
- context ๋ฐ๋ก ์ ๋ด์ฉ ์ฐธ๊ณ
- ๋จ๋ฐฉํฅ. SwiftUI์ ๋ณ๊ฒฝ์ฌํญ์ UIKit์ ํด๋น ํจ์๋ก ์ ๋ฌํ์ฌ UIKit์ ์ ๋ฐ์ดํธ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์ฌ์ฉ๋๋ฉฐ ๋ฐ๋๋ก UIKit์ ๋ณํ๋ฅผ SwiftUI์ View๋ก ์ ๋ฌํ๋ ๊ฒ์ ์๋
@Binding var url: URL?
func updateUIView(_ uiView: WKWebView, context: Context) {
if let url = url {
let request = URLRequest(url: url)
uiView.load(request)
}
}
- ๋ฐ์ธ๋ฉ ๋ url์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด WKWebView๋ฅผ ์ ๋ฐ์ดํธ ํจ
import SwiftUI
struct ContentView: View {
@State private var testValue = false
@State private var currentURLString = "https://tistory.com"
var body: some View {
VStack {
CustomWebView(urlString: $currentURLString)
Button {
testValue.toggle()
currentURLString = testValue ? "https://naver.com" : "https://tistory.com"
} label: {
Text("ํ ๊ธ ๋ฒํผ")
}
}
.padding()
}
}
#Preview {
ContentView()
}
(๋๋ฌด๋ ์ฌํ๊ฒ๋ ๊ฐ์๊ธฐ ํ๋ฐ์ ํฐ์ ๋ฒ ํ๋ก ๋๋ฆฐ ํ ํฐ์ด ๋ฒฝ๋์ด ๋ฌ์ ํ ์์ ๋ฒ ํ XCode 15.0์ ์ฐ๊ณ ์๋๋ฐ Preview ์ฝ๋๊ฐ ์์ ์
๋๋ค. #Preview๋ฅผ ์ฌ์ฉํ๋ฉด PreviewProvider ๋ถ๋ถ์ ๊ฐ๋ตํ๊ฒ ์ฝ๋ฉํ๊ณ canvas๋ก ๋ณผ์ ์์ต๋๋ค)
import SwiftUI
import WebKit
struct CustomWebView: UIViewRepresentable {
@Binding var urlString: String
func makeUIView(context: Context) -> WKWebView {
print("makeUIView")
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
print("updateUIView")
if let url = URL(string: urlString) {
let request = URLRequest(url: url)
uiView.load(request)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: CustomWebView
init(_ parent: CustomWebView) {
self.parent = parent
}
}
}
- ์ฒ์ ํ๋ฉด์ ๋ก๋ ๋๋ฉด mkaeUIView์ updateUIView๊ฐ ํธ์ถ๋จ -> ๋ฒํผ์ ๋๋ฅด๋ฉด SwiftUI View์ State ๊ฐ(url)์ด ๋ณ๊ฒฝ๋จ -> ์ด๋ฅผ ๋ฐ์ธ๋ฉํ๊ณ ์๋ UIKit์ WKWebView๋ updateUIView์์ ๋ณ๊ฒฝ๋ State ๊ฐ์ WKWebView์ ๋ฐ์ํจ
Coordinator Class
- Coordinator ํด๋์ค๋ UIKit์ delegate ๋ฅผ ์ฒ๋ฆฌํ๋๋ฐ ์ฌ์ฉ๋จ
import SwiftUI
import WebKit
struct CustomWebView: UIViewRepresentable {
@Binding var urlString: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: CustomWebView
init(_ parent: CustomWebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print(parent.urlString)
}
}
}
- WKWebView๋ฅผ ๊ตฌํํ๊ธฐ ์ํด UIViewRepresentable์ ์ฑํํ๋ CustomView๊ฐ ์๋ค๊ณ ํ ๋ WKNavigationDelegate๋ฅผ Coordinator ํด๋์ค๋ฅผ ํตํด ์ฌ์ฉํ ์ ์์
- ์ด๋ parent๋ ์ปค์คํ ํ ๋ทฐ ํ์ ์ด๋ฉฐ SwiftUI๋ก ๋ถํฐ ์ ๋ฌ๋ ๋ฐ์ธ๋ฉ ๊ฐ์ parent๋ก ๋ถํฐ ์ ๊ทผํ์ฌ ์ฌ์ฉํ ์ ์์
์ฐธ๊ณ ์ฌ์ดํธ
https://developer.apple.com/documentation/swiftui/uiviewrepresentable
'iOS ๐ > UIViewRepresentable' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SwiftUI] UIViewRepresentable UITextField์ done ๋ฒํผ ์ถ๊ฐํ๊ธฐ (0) | 2023.08.29 |
---|