SwiftUI-WebView 全面指南

介绍

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

效果

相关推荐
茶底世界之下5 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
2501_916007475 天前
苹果商店iOS应用上架费用全面解析:开发者计划与审核费用计算
android·ios·小程序·https·uni-app·iphone·webview
2501_916008895 天前
如何实现iOS App代码混淆:SwiftShield使用指南
android·ios·小程序·https·uni-app·iphone·webview
2501_915909065 天前
移动端开发工具链怎么组合比较好,iOS、Android、跨端三套配置方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
东坡肘子5 天前
一场关于 SwiftUI 动画的“原生”之争 -- 肘子的 Swift 周报 #154
人工智能·swiftui·swift
2501_916008895 天前
怎么用 Godot 导出 iOS 应用并上架 App Store?签名字段该填什么?
android·ios·小程序·https·uni-app·iphone·webview
2501_915918416 天前
iOS编程用什么软件好?主流工具Xcode、AppCode、CodeRunner与新兴快蝎对比
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
终端安全笔记6 天前
iOS 27 之后「策略空转」:设备升级不报错,但旧策略不再管它
android·网络·安全·ios·智能手机
9765033356 天前
iOS 上架 4.3a 被拒【uniapp专讲】
flutter·ios·objective-c·uniapp·swift
黑化旺仔7 天前
【OC】KVO
macos·ios·objective-c·cocoa