很多 App 都需要顯示 web 內容。iOS SDK 為開發者提供了 3 個選擇去顯示 web 內容:Mobile Safari、WKWebView、和 SFSafariViewController。在 iOS 14 以上的版本中,SwiftUI 框架 提供了一個名為 Link
的視圖,讓我們可以在 Mobile Safari 打開一條 web 連結。這是方法用起來非常簡單,你只需要這樣指明連結的文本和 URL 就可以了:
Link(destination: URL(string: "https://www.appcoda.com")!, label: {
Text("AppCoda")
.foregroundColor(.orange)
})
如此一來,文本連結就會以橙色顯示。當使用者點擊文本,App 就會在 Safari 瀏覽器打開連結。我們的設定並不限於文本連結。我們可以在 label
閉包 (closure) 中,改變程式碼來利用 Image
視圖或其他客製視圖,來顯示一個圖像連結。
但是,現時 SwiftUI 的版本並沒有內置的 web 視圖。如果我們想在 App 中顯示web 內容,就需要利用 UIKit 框架。在這篇教學中,我會帶大家一步步在 SwiftUI 專案中調用 (adopt) WKWebView
。
利用 UIViewRepresentable 協定來調用 WKWebView
如果你有整合 SwiftUI 和 UIKit 的經驗,應該會知道我們需要先調用 UIViewRepresentable
協定 (protocol),才可以使用 UIKit 的元件 (component)。
在這個範例中,我會建立一個新檔案 WebView.swift
,來在 SwiftUI 實作一個客製化的 Web 視圖。在 Project Navigator 中,右撃專案資料夾並選擇 New File…,然後選擇 Swift File 模版,並把檔案命名為 WebView.swift
。讓我們這樣更改檔案的內容:
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
var url: URL
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}
}
要在 SwiftUI 中使用 UIKit 視圖,我們需要使用 UIViewRepresentable
協定來包裝視圖。基本上,我們只需要在 SwiftUI 中創建一個 struct
,並讓它調用創建和管理 UIView
物件的協定就可以了。在上面的程式碼中,我們創建了一個 WebView
結構,並調用 UIViewRepresentable
協定,來實作所需的方法。
在 makeUIView
方法中,我們回傳了一個 WKWebView
的實例 (instance)。如此一來,我們就包裝好 UIKit 視圖,讓 SwiftUI 可以使用 Web 視圖。
makeUIView
方法負責創建和初始化視圖物件,而 updateUIView
方法則負責更新 UIKit 視圖的狀態。因此,我們會在 updateUIView
方法中加載特定的 URL。
現在,我們已經可以在 SwiftUI 專案中使用 WebView
了。轉換到 ContentView.swift
,並添加一個狀態變數 (state variable) 來儲存當前的連結。
@State private var showWebView = false
要顯示 Web 視圖,讓我們把 .sheet
修飾符 (modifier) 添加到 Button
視圖:
Button {
showWebView.toggle()
} label: {
Text("AppCoda")
}
.sheet(isPresented: $showWebView) {
WebView(url: URL(string: "https://www.appcoda.com")!)
}
我們會利用 sheet 來顯示客製的 Web 視圖。讓我們在模擬器上運行 App 來測試一下,點擊按鈕時,App 會顯示一個 Web 視圖,以在模態視圖 (modal view) 中加載網站。
我們可以利用相同的技巧,來在 SwiftUI 專案中整合 SFSafariViewController
,這個部分我就留給大家試著做吧!
如果你想了解更多 SwiftUi 的技巧,可以看看我們最新的 Swift 書籍。