加载 webview 时加载动画卡住/冻结
Posted
技术标签:
【中文标题】加载 webview 时加载动画卡住/冻结【英文标题】:Loading animation stucked/freezed when webview loads 【发布时间】:2019-02-27 10:09:53 【问题描述】:我加载进度加载动画,当来自 Alamofire 的响应到来时,我使用部分响应来构建我需要在 wkwebview 中加载的完整 url,然后触发 webview.load(..)。
我的问题是,一旦 webview.load(..) 开始发生,进度加载动画就会卡住并一直卡住,直到我 hide() 它。
我怎样才能让我的动画在 webview 开始加载页面的同时继续移动?
MyViewController.swift
class MyViewController: UIViewController, WKScriptMessageHandler
var webView: WKWebView?
@IBOutlet weak var webViewContainer: UIView!
var webConfig:WKWebViewConfiguration
get
let webCfg:WKWebViewConfiguration = WKWebViewConfiguration()
let userController:WKUserContentController = WKUserContentController()
userController.add(self, name: "mycontroller")
webCfg.userContentController = userController;
return webCfg;
override func viewDidLoad()
super.viewDidLoad()
webView = WKWebView (frame: webViewContainer.bounds, configuration: webConfig)
webView!.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webView?.scrollView.isScrollEnabled = false
webViewContainer.addSubview(webView!)
loadWebview()
func loadWebview()
Loading.shared.show(self.view)
Alamofire.request(MYAPI, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil)
.responseJSON response in
let url = URL(string: "https://path-to-load/\(response.key)")
self.webView!.load(URLRequest(url: url!))
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
let message = message.body as! [String:AnyObject]
let event = message["event"] as? String ?? "empty"
switch (event)
case "loading-finished":
DispatchQueue.main.async
Loading.shared.hide(animated: true)
break
default:
break
Loading.swift
public class Loading
var blurredEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
let imageView = UIImageView(image: UIImage(named: "loading_image"))
class var shared: Loading
struct LoadingStatic
static let instance: Loading = Loading()
return LoadingStatic.instance
init()
imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
imageView.contentMode = .scaleToFill
blurredEffectView.contentView.addSubview(imageView)
public func show(_ view: UIView, inView: Bool = false)
var window: UIView!
if inView == false, let w = view.window
window = w
else
window = view
if blurredEffectView.superview == window
return
let rotation: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.toValue = NSNumber(value: Double.pi * 2)
rotation.duration = 1
rotation.isCumulative = true
rotation.repeatCount = Float.greatestFiniteMagnitude
imageView.layer.add(rotation, forKey: "rotationAnimation")
imageView.center = window.center
blurredEffectView.frame = window.bounds
window.addSubview(blurredEffectView)
blurredEffectView.fadeIn()
【问题讨论】:
你试过把webView.load
放在DispatchQueue.main.async
里面吗?
是的,但加载仍然冻结
【参考方案1】:
可能的解决方案:
1) 当您想要全屏加载时,在应用程序窗口中进行加载(默认为 inview == false)并将 loadWebview() 保留在 viewDidLoad 中
public func show(_ view: UIView? = nil, inView: Bool = false)
var window: UIView!
if inView == false, let w = UIApplication.shared.delegate?.window
window = w
else
window = view
...
2) 将 loadWebview() 从 viewDidLoad 移动到 viewDidAppear
这里移动的重要部分是Loading.shared.show(self.view)
。在完成布局之前,我无法为视图的组件设置动画(这恰好发生在 viewDidAppear() 中)。
更多细节: viewDidLoad
在 MyViewController 初始化并初始化主视图之后但在视图呈现给 UI 之前被调用。这意味着 viewDidLoad 允许我在将 ViewController 和 View 显示给用户进行交互之前设置它。
虽然这是一个不错且快速的解决方案,但在某些情况下,这可能无法按预期工作,因为 viewDidAppear 可以调用两次, 并因此显示加载视图两次,这将导致奇怪的用户体验。
【讨论】:
以上是关于加载 webview 时加载动画卡住/冻结的主要内容,如果未能解决你的问题,请参考以下文章