UIActivityIndicatorView为nil崩溃求助:已关联Storyboard仍报错
嘿,我一眼就看出问题出在哪了——你重写了loadView方法,但没有正确加载Storyboard里的视图层级,导致你的activityIndicator这个Outlet根本没被初始化,自然就成nil了!
问题根源
默认情况下,当ViewController从Storyboard实例化时,系统会自动调用loadView来加载Storyboard中定义的view,同时完成所有Outlet的关联。但你现在重写了loadView,只创建了webView并直接赋值给self.view,完全跳过了Storyboard的视图加载流程,那原来在Storyboard里的activityIndicator当然找不到对应的父视图,也就没法完成关联了。
解决方案一:保留Storyboard布局(推荐)
如果你还想继续用Storyboard里布置好的activityIndicator,只需要调整webView的初始化逻辑,不要直接覆盖self.view,而是把webView添加到Storyboard加载的view上:
import UIKit import WebKit class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { var webView: WKWebView! @IBOutlet weak var activityIndicator: UIActivityIndicatorView! override func viewDidLoad() { super.viewDidLoad() // 初始化webView并添加到当前view中 let webConfiguration = WKWebViewConfiguration() webView = WKWebView(frame: view.bounds, configuration: webConfiguration) webView.uiDelegate = self webView.navigationDelegate = self // 把webView放到最底层,确保activityIndicator能显示在上方 view.insertSubview(webView, at: 0) // 设置自动布局让webView填满整个view webView.translatesAutoresizingMaskIntoConstraints = false 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) ]) // 加载测试网页 guard let url = URL(string: "https://www.example.com") else { return } webView.load(URLRequest(url: url)) } // 通过WKNavigationDelegate控制指示器状态 func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { activityIndicator.startAnimating() } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { activityIndicator.stopAnimating() } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { activityIndicator.stopAnimating() } }
解决方案二:完全代码创建视图
如果你想彻底抛弃Storyboard,用纯代码实现所有视图,那直接去掉Outlet,手动创建activityIndicator即可:
import UIKit import WebKit class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { var webView: WKWebView! var activityIndicator: UIActivityIndicatorView! override func loadView() { let webConfiguration = WKWebViewConfiguration() webView = WKWebView(frame: .zero, configuration: webConfiguration) webView.uiDelegate = self webView.navigationDelegate = self self.view = webView // 代码创建activityIndicator activityIndicator = UIActivityIndicatorView(style: .large) activityIndicator.translatesAutoresizingMaskIntoConstraints = false activityIndicator.hidesWhenStopped = true webView.addSubview(activityIndicator) // 设置指示器居中布局 NSLayoutConstraint.activate([ activityIndicator.centerXAnchor.constraint(equalTo: webView.centerXAnchor), activityIndicator.centerYAnchor.constraint(equalTo: webView.centerYAnchor) ]) } override func viewDidLoad() { super.viewDidLoad() guard let url = URL(string: "https://www.example.com") else { return } webView.load(URLRequest(url: url)) } // 同样实现导航代理方法控制指示器 func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { activityIndicator.startAnimating() } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { activityIndicator.stopAnimating() } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { activityIndicator.stopAnimating() } }
两种方案选哪种取决于你的开发习惯:第一种适合已经在Storyboard里完成了部分布局的场景,第二种适合纯代码驱动的项目。
内容的提问来源于stack exchange,提问作者mistakeNot
相关产品推荐
相关产品推荐

