如何在WKWebView加载完成后隐藏ProgressView并修复状态栏占位问题
解决WKWebView加载YouTube视频后隐藏ProgressView的问题
嗨,我来帮你搞定这个问题!要解决返回主页后ProgressView占位遮挡元素的问题,核心是利用WKNavigationDelegate监听WebView的加载状态,在视频页面加载完成(或加载失败)时彻底隐藏ProgressView,让它不再占用布局空间。
具体实现步骤:
让你的ViewController遵守WKNavigationDelegate协议
在类定义处添加协议声明,这样才能接收WebView的加载回调。设置WebView的navigationDelegate为当前ViewController
初始化WKWebView时,把它的导航代理指向self,确保能收到加载状态的通知。实现代理方法控制ProgressView的显示/隐藏
通过didFinish(加载完成)和didFail(加载失败)两个代理方法,在合适的时机隐藏ProgressView;如果需要显示加载进度,还可以监听WebView的estimatedProgress属性来更新进度条。
修改后的完整代码示例:
import UIKit import WebKit class VideoPlayViewController: UIViewController, WKNavigationDelegate { // 假设你的ProgressView是代码创建的(Storyboard创建的话只需关联IBOutlet) private let progressView: UIProgressView = { let view = UIProgressView(progressViewStyle: .default) view.translatesAutoresizingMaskIntoConstraints = false return view }() private var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() // 初始化WKWebView并设置代理 webView = WKWebView(frame: view.bounds) webView.translatesAutoresizingMaskIntoConstraints = false webView.navigationDelegate = self view.addSubview(webView) // 添加ProgressView到视图并设置约束(这里假设放在顶部安全区) view.addSubview(progressView) NSLayoutConstraint.activate([ webView.topAnchor.constraint(equalTo: view.topAnchor), webView.leadingAnchor.constraint(equalTo: view.leadingAnchor), webView.trailingAnchor.constraint(equalTo: view.trailingAnchor), webView.bottomAnchor.constraint(equalTo: view.bottomAnchor), progressView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), progressView.leadingAnchor.constraint(equalTo: view.leadingAnchor), progressView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) // 加载YouTube视频URL if let videoURL = URL(string: "https://www.youtube.com/watch?v=你的视频ID") { webView.load(URLRequest(url: videoURL)) } // 监听加载进度(可选,用于更新ProgressView的进度值) webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil) } // 监听进度变化,更新ProgressView override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == #keyPath(WKWebView.estimatedProgress), let progress = change?[.newKey] as? Double else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) return } progressView.progress = Float(progress) } // MARK: - WKNavigationDelegate // 页面加载完成时,隐藏ProgressView func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 用动画隐藏,过渡更自然 UIView.animate(withDuration: 0.3) { self.progressView.isHidden = true } // 移除进度监听,避免内存泄漏 webView.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress)) } // 加载失败时也隐藏ProgressView,防止一直显示 func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { UIView.animate(withDuration: 0.3) { self.progressView.isHidden = true } webView.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress)) } // 可选:页面开始加载时显示ProgressView func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { progressView.isHidden = false progressView.progress = 0.0 } deinit { // 确保移除观察者,避免内存泄漏 webView?.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress)) } }
关键说明:
isHidden = true的作用:设置这个属性后,ProgressView不仅会隐藏,还会完全脱离布局流,不会再占用状态栏位置的空间,彻底解决遮挡问题。- 代理方法的可靠性:
didFinish是WebView确认页面所有资源加载完成的回调,比单纯监听进度到1.0更可靠(毕竟YouTube的视频资源可能在页面加载后才开始加载)。 - 内存泄漏防护:记得在
didFinish、didFail和deinit中移除进度观察者,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Mason Bose
相关产品推荐
相关产品推荐

