SwiftUI WebView 全面指南

Viewed 0

SwiftUI-WebView 全面指南

介绍

在 iOS 开发中,网页内容展示是许多应用的必要功能,无论是用于显示帮助中心、隐私政策,还是嵌入在线课程或文档预览,WebView 都发挥着关键作用。SwiftUI 7.0 通过集成 WebKit 模块,提供了便捷的方式来实现网页加载、导航控制以及 JavaScript 交互。本文将从基础到高级,逐步介绍 SwiftUI 中 WebView 的使用方法。

网页加载

使用 WebView 前,首先需要导入 WebKit 模块,然后可以通过直接加载 URL 或使用 WebPage 类型来实现网页加载和状态管理。

直接加载 URL

以下是一个简单的示例,展示如何直接加载一个 URL:

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 状态等信息。

基本用法

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))
            }
    }
}

内容控制

通过 WebPage,可以轻松访问网页标题和加载进度,并在界面中显示:

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 或限制访问域名。可以通过实现 NavigationDeciding 协议来实现。

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 {
            return .allow
        } else {
            return .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 交互

WebView 支持与网页内的 JavaScript 进行交互,例如调用函数或获取返回值。SwiftUI 提供了异步调用的便利方式。

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
                }
        }
    }
}
0 Answers