如何解决WKWebView选择上传图片后自动刷新、图片无法正常展示的问题
问题根因
你的代码核心问题出在网页加载逻辑的触发时机配置错误:
你将POST请求加载网页的逻辑放在了viewWillAppear生命周期方法中,该方法会在当前ViewController每次回到前台可见状态时执行。当你唤起系统相册/相机选择界面时,当前ContinueViewController会被临时遮盖,选择完照片回到当前页面时viewWillAppear会再次触发,导致webview重新加载网页,原有页面的所有状态(包括刚选中的待上传图片)都会被清空,就出现了选中图片后页面刷新、图片无法展示的问题。
修复方案
你可以根据业务需求选择以下任意一种方案修改:
方案1:调整加载触发时机(推荐)
将网页加载逻辑从viewWillAppear迁移到viewDidLoad方法中,仅在页面首次初始化时加载一次网页,后续页面回到前台不会重复触发加载。修改后参考代码如下:
import UIKit import WebKit import Alamofire class ContinueViewController: UIViewController, WKUIDelegate { @IBOutlet weak var activityView: UIActivityIndicatorView! @IBOutlet weak var webview: WKWebView! func getPostString(params:[String:Any]) -> String{ var data = [String]() for(key, value) in params { data.append(key + "=\(value)") } return data.map { String($0) }.joined(separator: "&") } var url: URL? var traderCategoryId = 0, tradeSkillId = 0 // 注意:原代码中params用到的id变量未定义,需要你自行补全该变量的声明 override func viewDidLoad() { super.viewDidLoad() webview.navigationDelegate = self self.navigationController?.navigationBar.isHidden = false webview.uiDelegate = self // 将加载逻辑移到这里,仅执行一次 activityView.startAnimating() guard let url = self.url else { return } var req = URLRequest(url: url) let params = ["id" : id,"trader_skills" : tradeSkillId] let postString = self.getPostString(params: params) req.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") req.httpMethod = "POST" req.httpBody = postString.data(using: .utf8) self.webview.load(req) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 移除原有的加载逻辑 } } extension ContinueViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { activityView.stopAnimating() } } extension UIImagePickerController { open override func viewDidLoad() { super.viewDidLoad() // iOS 13以上如果出现选择界面弹出异常可以放开下面的注释 // self.modalPresentationStyle = .fullScreen } }
方案2:新增标记位控制加载
如果业务确实需要页面每次回到前台都刷新内容,可新增标记位区分是否是从媒体选择界面回来,避免重复加载:
// 在类中新增标记位变量 var hasLoaded = false override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) guard !hasLoaded else { return } hasLoaded = true activityView.startAnimating() guard let url = self.url else { return } var req = URLRequest(url: url) let params = ["id" : id,"trader_skills" : tradeSkillId] let postString = self.getPostString(params: params) req.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") req.httpMethod = "POST" req.httpBody = postString.data(using: .utf8) self.webview.load(req) }
额外检查项
- 确认info.plist中已经正确配置
NSPhotoLibraryUsageDescription、NSCameraUsageDescription权限描述 - iOS 13以上系统如果出现媒体选择界面弹出异常,可以将UIImagePickerController的
modalPresentationStyle设置为.fullScreen
内容的提问来源于stack exchange,提问作者Dhiren
相关产品推荐
相关产品推荐

