在iOS应用开发过程中,当需要展示文件下载、页面加载等进度场景时,借助HTML5原生的进度条组件可以减少原生UI的编写成本,实现跨端样式统一。下面详细介绍iOS调用HTML5进度条组件的具体实现方法。

一、HTML5进度条组件编写
首先我们需要编写一个包含HTML5进度条的基础页面,进度条使用<progress>标签实现,同时提供控制进度更新的JavaScript方法,方便iOS端调用。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5进度条页面</title>
<style>
.progress-container {
width: 80%;
margin: 50px auto;
text-align: center;
}
progress {
width: 100%;
height: 20px;
}
.progress-text {
margin-top: 10px;
font-size: 16px;
}
</style>
</head>
<body>
<div class="progress-container">
<progress id="myProgress" value="0" max="100"></progress>
<div class="progress-text" id="progressText">当前进度:0%</div>
</div>
<script>
// 更新进度条的方法,供iOS端调用
function updateProgress(value) {
var progressBar = document.getElementById("myProgress");
var progressText = document.getElementById("progressText");
if (value >= 0 && value <= 100) {
progressBar.value = value;
progressText.innerText = "当前进度:" + value + "%";
}
}
// 重置进度条的方法
function resetProgress() {
var progressBar = document.getElementById("myProgress");
var progressText = document.getElementById("progressText");
progressBar.value = 0;
progressText.innerText = "当前进度:0%";
}
</script>
</body>
</html>
二、使用UIWebView调用HTML5进度条
UIWebView是iOS早期提供的网页加载控件,虽然现在已经被标记为过时,但仍有部分旧项目在使用,下面介绍其调用方式。
1. 加载HTML页面
先将上面的HTML文件添加到项目资源中,然后在ViewController中加载该页面。
#import "ViewController.h"
@interface ViewController () <UIWebViewDelegate>
@property (nonatomic, strong) UIWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// 初始化UIWebView
self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
self.webView.delegate = self;
[self.view addSubview:self.webView];
// 加载本地HTML文件
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"progress" ofType:@"html"];
NSURL *htmlUrl = [NSURL fileURLWithPath:htmlPath];
NSURLRequest *request = [NSURLRequest requestWithURL:htmlUrl];
[self.webView loadRequest:request];
// 添加模拟进度更新的按钮
UIButton *updateBtn = [UIButton buttonWithType:UIButtonTypeSystem];
updateBtn.frame = CGRectMake(50, self.view.bounds.size.height - 100, 100, 40);
[updateBtn setTitle:@"更新进度" forState:UIControlStateNormal];
[updateBtn addTarget:self action:@selector(updateProgressAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:updateBtn];
UIButton *resetBtn = [UIButton buttonWithType:UIButtonTypeSystem];
resetBtn.frame = CGRectMake(200, self.view.bounds.size.height - 100, 100, 40);
[resetBtn setTitle:@"重置进度" forState:UIControlStateNormal];
[resetBtn addTarget:self action:@selector(resetProgressAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:resetBtn];
}
// 模拟进度更新
- (void)updateProgressAction {
static int currentProgress = 0;
currentProgress += 10;
if (currentProgress > 100) {
currentProgress = 100;
}
// 调用JS方法更新进度
NSString *jsStr = [NSString stringWithFormat:@"updateProgress(%d)", currentProgress];
[self.webView stringByEvaluatingJavaScriptFromString:jsStr];
}
// 重置进度
- (void)resetProgressAction {
[self.webView stringByEvaluatingJavaScriptFromString:@"resetProgress()"];
}
@end
2. 关键说明
UIWebView调用JavaScript方法使用stringByEvaluatingJavaScriptFromString:接口,直接将需要执行的JS代码作为字符串传入即可,上述代码中调用了HTML页面定义的updateProgress和resetProgress方法。
三、使用WKWebView调用HTML5进度条
WKWebView是苹果推荐的替代UIWebView的控件,性能更好,支持更多特性,是现在新项目的首选。
1. 基础调用实现
WKWebView调用JS方法使用evaluateJavaScript:completionHandler:接口,异步执行JS代码并可以获取返回值。
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
var currentProgress = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// 初始化WKWebView
webView = WKWebView(frame: view.bounds)
webView.navigationDelegate = self
view.addSubview(webView)
// 加载本地HTML文件
if let htmlPath = Bundle.main.path(forResource: "progress", ofType: "html") {
let htmlUrl = URL(fileURLWithPath: htmlPath)
webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl)
}
// 添加进度更新按钮
let updateBtn = UIButton(type: .system)
updateBtn.frame = CGRect(x: 50, y: view.bounds.height - 100, width: 100, height: 40)
updateBtn.setTitle("更新进度", for: .normal)
updateBtn.addTarget(self, action: #selector(updateProgress), for: .touchUpInside)
view.addSubview(updateBtn)
let resetBtn = UIButton(type: .system)
resetBtn.frame = CGRect(x: 200, y: view.bounds.height - 100, width: 100, height: 40)
resetBtn.setTitle("重置进度", for: .normal)
resetBtn.addTarget(self, action: #selector(resetProgress), for: .touchUpInside)
view.addSubview(resetBtn)
}
@objc func updateProgress() {
currentProgress += 10
if currentProgress > 100 {
currentProgress = 100
}
// 调用JS方法更新进度
let jsStr = "updateProgress((currentProgress))"
webView.evaluateJavaScript(jsStr) { (result, error) in
if let error = error {
print("调用JS出错:(error.localizedDescription)")
}
}
}
@objc func resetProgress() {
currentProgress = 0
webView.evaluateJavaScript("resetProgress()") { (result, error) in
if let error = error {
print("调用JS出错:(error.localizedDescription)")
}
}
}
}
2. 监听HTML5进度条变化
如果需要在iOS端获取HTML5进度条的当前值,可以让HTML页面主动发送消息给iOS端,通过WKWebView的WKScriptMessageHandler实现。
首先修改HTML的JS代码,添加消息发送逻辑:
<script>
function updateProgress(value) {
var progressBar = document.getElementById("myProgress");
var progressText = document.getElementById("progressText");
if (value >= 0 && value <= 100) {
progressBar.value = value;
progressText.innerText = "当前进度:" + value + "%";
// 发送进度变化消息给iOS端
window.webkit.messageHandlers.progressUpdate.postMessage(value);
}
}
</script>
然后iOS端配置消息监听:
// 初始化WKWebView时添加配置 let config = WKWebViewConfiguration() config.userContentController.add(self, name: "progressUpdate") webView = WKWebView(frame: view.bounds, configuration: config)
实现WKScriptMessageHandler协议方法接收消息:
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "progressUpdate" {
if let progressValue = message.body as? Int {
print("HTML5进度条当前进度:(progressValue)%")
}
}
}
}
四、注意事项
- 加载本地HTML文件时,如果使用WKWebView加载,需要注意iOS的沙盒权限,使用
loadFileURL:allowingReadAccessTo:方法确保可以正确读取文件。 - 调用JavaScript方法时,参数格式要符合JS语法,字符串参数需要加单引号或者双引号转义。
- 使用WKWebView的消息监听时,需要在合适的时机移除监听,避免内存泄漏,比如在
deinit方法中调用userContentController.removeScriptMessageHandler(forName:)。 - 如果HTML页面是从远程服务器加载,需要确保在info.plist中配置了允许HTTP请求,或者使用HTTPS协议加载页面。