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 a
updateUIView
orupdateNSView
view to handle view updates.
The following code creates a web view that displays HTML text:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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: