Using a UIKit or AppKIt View in SwiftUI
When to Wrap a UIKit or AppKit View
There are two cases where you would wrap a UIKit or AppKit view in a SwiftUI app. The first case is your app needs a view that SwiftUI doesn’t have. If your app needs to show web content or a PDF file, you must use a WebKit web view or PDFKit’s PDF view. SwiftUI currently doesn’t have a native web view or PDF view.
The second case is your app needs to do something that a SwiftUI view can’t do. To let people edit rich text in your app, you must use UITextView
or NSTextView
. SwiftUI’s TextEditor
view only allows plain text editing. Text views are a common control where you have to drop down to UIKit or AppKit because SwiftUI’s text editor is very limited currently.
Wrapping a UIKit or AppKit View
To wrap a UIKIt or AppKit view in a SwiftUI app, perform the following steps:
- Create a struct that conforms to the
UIViewRepresentable
(iOS) orNSViewRepresentable
(Mac) protocols. - Write a
makeUIView
ormakeNSView
function to create the UIKit or AppKit view. - Write an
updateUIView
orupdateNSView
function to handle view updates.
The following code creates a web view that displays HTML text:
import WebKit
import SwiftUI
struct WebView: UIViewRepresentable {
var html: String
init(html: String) {
self.html = html
}
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.loadHTMLString(html, baseURL: nil)
}
}
Notice that makeUIView
returns the view type. The view type is also the type of the first argument to updateUIView
.
After creating the view struct, you can add the view as part of the body of a SwiftUI view the same way you would add one of SwiftUI’s native views.
Examples and Further Reading
I have a demo project on GitHub that wraps a web view in a multi-platform SwiftUI app.
The CodeEditor package wraps a text view that supports syntax highlighting. It’s a more complex example than my demo project.
The following articles have additional information on using UIKit and AppKit views in SwiftUI: