无法在第二个视图控制器中更新我的 UIImage

Posted

技术标签:

【中文标题】无法在第二个视图控制器中更新我的 UIImage【英文标题】:cannot update my UIImage in the second view controller 【发布时间】:2017-11-28 02:51:05 【问题描述】:

我在尝试从我的 JSON api 调用加载图像时遇到问题。基本上我已经创建了一个函数,它将调用我的 API 并获取图像 URL,然后将其显示在第二个视图控制器中。目前我可以清楚地看到我的 URL 已正确传递,因为我已在控制台中打印它。但是,当我尝试更新 UIImage 时,我收到一条错误消息:

致命错误:在展开可选值时意外发现 nil

这是我的模型类文件:

class Exercise 
private var _id: Int!
private var _exerciseURL: String!
private var _imageUrl: URL!

var id: Int 

    return _id


var exerciseURL: String 

    return _exerciseURL


var imageURL: URL 

    return _imageUrl // debug navigator is pointing at this line



init(name: String, description: String, id: Int) 
    self._id = id

    self._exerciseURL = "https://wger.de/api/v2/exerciseimage/?exercise=\(self.id)"

    self._imageUrl = URL(string: "")



func parseImageData() 

    let urlPath = _exerciseURL
    let url = URL(string: urlPath!)

    let task = URLSession.shared.dataTask(with: url!)  (data, response, error) in

        if error != nil 
            print("Error while parsing JSON")
        
        else 

            do 
                if let data = data,
                    let fetchedImageData = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String:Any],
                    let images = fetchedImageData["results"] as? [[String: Any]] 


                    for eachImage in images 
                        let imageUrl = eachImage["image"] as! String
                        self._imageUrl = URL(string: imageUrl)
                    

                    print(self.imageURL)


                
            
            catch 
                print("Error while parsing data.")
            
        
    
    task.resume()



这是我的第二个视图控制器,它应该根据其 url 更新图像。

class ExerciseDetailViewController: UIViewController 

var exercise: Exercise!

@IBOutlet weak var exerciseImage: UIImageView!

override func viewDidLoad() 
    super.viewDidLoad()

    exercise.parseImageData()

    let data = NSData(contentsOf: exercise.imageURL)
    exerciseImage.image = UIImage(data: data as! Data)


    // Do any additional setup after loading the view.



每当我尝试评论时

let data = NSData(contentsOf: exercise.imageURL) 
exerciseImage.image = UIImage(data: data as! Data)

然后测试我的结果,我可以看到我的语句“print(self.imageURL)”在第二个 VC 的控制台中正确显示 URL。另外,代码中未显示的同一对象的其他变量,例如名称等,通过其他标签正确显示。

【问题讨论】:

***.com/questions/24643522/… 我不确定是否是这种情况,因为每当我尝试注释掉 'let data = NSData(contentsOf: exercise.imageURL) exerciseImage.image = UIImage(data: data as!Data)' 和然后测试我的结果,我可以看到我的语句 'print(self.imageURL)' 在第二个 VC 的控制台中正确显示 URL。 是的,我真的不了解 Swift,我只是试图通过其他帖子帮助人们指出正确的方向,而不是试图关闭他们的问题。 exercise.imageURL 也是基于 HTTPS 的,而不是纯 HTTP 吗? 您必须确保executive.imageURL 是URL 的形式,而不是字符串中的HTTPS/HTTP 链接。您必须将其转换为 URL 形式: let imageURL = URL(string: exercise.imageURL.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!) 【参考方案1】:

问题是您的网络请求URLSession.shared.dataTask(with: url!) 是异步的,并且您在网络请求完成之前访问exercise.imageURLimageURL 仍然是nil

为了更好地了解正在发生的事情,我鼓励您在以下行设置断点:

// 1. In parseImageData()
self._imageUrl = URL(string: imageUrl)

// 2. In viewDidLoad()
let data = NSData(contentsOf: exercise.imageURL)

你会看到第二个断点首先被激活。

您需要做的是等待网络请求和解析完成。为此,请阅读 Swift 中的完成处理程序并更改 parseImageData() 以接受完成处理程序。查看此答案以获取示例函数https://***.com/a/43317287/2247399

【讨论】:

以上是关于无法在第二个视图控制器中更新我的 UIImage的主要内容,如果未能解决你的问题,请参考以下文章

导航返回时导航控制器和视图未更新

如何在第二个视图控制器上显示核心数据?

为啥没有调用第二个单点触控视图控制器工具栏按钮事件处理程序

关闭 Popover 后更新第一个视图

导航控制器在第二个视图控制器中为零

如何在第二个 ViewController 表格视图中使用模型快速显示第一个 ViewController 值