介绍
在 iOS 开发中,网页内容展示几乎是每个 App 的刚需场景。无论是展示帮助中心、隐私政策,还是嵌入在线课程、文档预览等,WebView 都扮演着重要角色。SwiftUI 7.0 通过 WebKit 模块,可以轻松实现网页加载、导航控制以及 JavaScript 交互功能。本文将从基础到高级,循序渐进介绍 SwiftUI 中的 WebView 用法。
网页加载
- 在使用 WebView 前,需要先导入 WebKit 模块。
- 借助 URL 或者 WebPage,可以实现网页加载与状态管理功能。
直接加载URL
swift
import SwiftUI
import WebKit
struct ContentView: View {
let url = URL(string: "https://www.apple.com.cn")!
var body: some View {
WebView(url: url)
}
}
使用WebPage
WebPage 是一个功能更强的类型,它不仅能加载网页,还能实时监控网页的标题、加载进度、URL 状态等信息。
基本用法
swift
import SwiftUI
import WebKit
struct ContentView: View {
@State private var webPage = WebPage()
let url = URL(string: "https://www.apple.com.cn")!
var body: some View {
WebView(webPage)
.ignoresSafeArea()
.onAppear {
webPage.load(URLRequest(url: url))
}
}
}
内容控制
swift
import SwiftUI
import WebKit
struct ContentView: View {
@State private var webPage = WebPage()
let url = URL(string: "https://www.apple.com.cn")!
var body: some View {
VStack {
// 标题
Text(webPage.title)
// 进度
ProgressView("", value: webPage.estimatedProgress, total: 1.0)
// 内容
WebView(webPage)
.ignoresSafeArea()
.onAppear {
webPage.load(URLRequest(url: url))
}
}
}
}
高级控制
导航策略
如果需要在网页跳转时进行判断(例如拦截某些 URL、仅允许访问特定域名),可以自定义导航策略。
swift
import SwiftUI
import WebKit
// 导航处理方式
struct NavigationDecider: WebPage.NavigationDeciding {
func decidePolicy(for response: WebPage.NavigationResponse) async -> WKNavigationResponsePolicy {
if response.response.url?.absoluteString.starts(with: "https://www.apple.com") == true {
.allow
} else {
.cancel
}
}
}
struct ContentView: View {
@State private var webPage: WebPage = {
var config = WebPage.Configuration()
config.applicationNameForUserAgent = "User Agent"
return WebPage(configuration: config, navigationDecider: NavigationDecider())
}()
let url = URL(string: "https://www.baidu.com")!
var body: some View {
VStack {
Text(webPage.title)
ProgressView("", value: webPage.estimatedProgress, total: 1.0)
WebView(webPage)
.ignoresSafeArea()
.onAppear {
webPage.load(URLRequest(url: url))
}
}
}
}
JavaScript 交互
许多场景需要与网页内部的 JavaScript 进行交互,如调用函数、获取返回值等。SwiftUI 也提供了非常方便的异步调用方式。
代码
swift
import SwiftUI
import WebKit
struct ContentView: View {
@State private var webPage = WebPage()
@State private var title = ""
let url = URL(string: "https://www.apple.com.cn")!
var body: some View {
VStack {
title.isEmpty ? Text(webPage.title) : Text(title)
ProgressView("", value: webPage.estimatedProgress, total: 1.0)
WebView(webPage)
.ignoresSafeArea()
.onAppear {
webPage.load(URLRequest(url: url))
}
.task {
try? await Task.sleep(for: .seconds(3), clock: .suspending)
let jsResult = try? await webPage.callJavaScript(
"""
console.log("Hello SwiftUI")
return "JavaScript Returned Value"
"""
)
title = jsResult as! String
}
}
}
}
效果
