如何在iOS中将解析读取的图像与屏幕显示同步 [英] How to synchronize a parse-read image with screen display in iOS

查看:104
本文介绍了如何在iOS中将解析读取的图像与屏幕显示同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在TableViewController中,我显示从解析数据库读取的记录表.每个单元格显示一个缩略图,一个标题和一个注释.选择行后,将保存行索引,并启动到detailView Controller的segue,detailView Controller显示保存在全局UIImage变量(noteImage)中的图像.在prepareForSegue中,我在后台调用loadImageFromParse,它读取与缩略图关联的图像并将其保存到noteImage中.

我的问题是,从解析中读取图像会稍有延迟,因此detailViewController显示空白.当我从detailViewController备份到TableViewController并重新选择该行时,将显示图片.

我需要一种方法来保持segue调用,直到从Parse中读取了图像为止.

任何帮助将不胜感激.

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    selectedRow = indexPath.row
    self.performSegueWithIdentifier("NoteSegue", sender: self)
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "NoteSegue"{
        let vc = segue.destinationViewController as NoteViewController
        vc.selectedRow = selectedRow
        self.loadImageFromParse(objectIds[selectedRow])
    }
}

// Load one image from parse
func loadImageFromParse (objectId: String) {

    var query = PFQuery(className:"Record")
    query.whereKey("objectId", equalTo:objectId)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            println("Successfully retrieved \(objects.count) records.")
            for object in objects {
                let userImageFile = object["image"] as PFFile!
                userImageFile.getDataInBackgroundWithBlock {
                    (imageData: NSData!, error: NSError!) -> Void in
                    if error == nil {
                        noteImage = UIImage(data:imageData)!
                        println("Image successfully retrieved")
                    }
                }
            }

        } else {
            NSLog("Error: %@ %@", error, error.userInfo!)
        }
    }
}

解决方案

您说的是:

我需要一种方法来保持segue调用,直到从Parse中读取了图像为止.

正如我想您现在猜到的那样,这并不是真正的最佳方法.最好是开始过渡到下一个场景,如果图像不可用,请提供UIActivityIndicatorView(微调器),检索图像,完成后,移除微调器并显示图像.但是延迟固定的时间并不能很好地工作:有时候,您会使用户等待的时间超过了需要的时间;有时您不会等待足够长的时间. (当然,同步执行请求始终不是正确的方法.)

如果将此图像检索代码放在目标视图控制器中,则可能会简化此实现.要让一个视图控制器启动一个异步过程并通知另一个视图完成是很尴尬的(尽管可以通过明智地使用通知来完成).但是在此示例中(在选择一行之前您不知道要检索哪个图像),我看不到有什么好处.

综上所述,该代码正在启动两个异步请求,一个请求用于Record,另一个请求用于图像本身.我想知道在填充此初始表视图时是否可以捕获此Record信息.这样,您只需要检索图像.现在,也许Parse进行了一些缓存,并且Record的检索无论如何都是非常快的(因此在重构代码之前对其进行基准测试),但是如果没有,则可能需要在填充原始表视图时捕获PFFile对象,使您不必进行两次查询.

In TableViewController I display a table of records read from a parse database. Each cell displays a thumbnail, a title and a note. When a row is selected, the row index is saved and a segue is initiated to a detailView Controller which displays the image saved in a global UIImage variable (noteImage). In prepareForSegue I invoke loadImageFromParse in background which reads the image associated with the thumbnail and saves it into noteImage.

My problem is that there is a slight delay for the image to be read from parse so the detailViewController displays a blank. When I back up from the detailViewController to the TableViewController and reselect the row the picture is displayed.

I need a way to hold the segue invocation till the image has been read from Parse.

Any help would be appreciated.

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    selectedRow = indexPath.row
    self.performSegueWithIdentifier("NoteSegue", sender: self)
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "NoteSegue"{
        let vc = segue.destinationViewController as NoteViewController
        vc.selectedRow = selectedRow
        self.loadImageFromParse(objectIds[selectedRow])
    }
}

// Load one image from parse
func loadImageFromParse (objectId: String) {

    var query = PFQuery(className:"Record")
    query.whereKey("objectId", equalTo:objectId)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            println("Successfully retrieved \(objects.count) records.")
            for object in objects {
                let userImageFile = object["image"] as PFFile!
                userImageFile.getDataInBackgroundWithBlock {
                    (imageData: NSData!, error: NSError!) -> Void in
                    if error == nil {
                        noteImage = UIImage(data:imageData)!
                        println("Image successfully retrieved")
                    }
                }
            }

        } else {
            NSLog("Error: %@ %@", error, error.userInfo!)
        }
    }
}

解决方案

You said:

I need a way to hold the segue invocation till the image has been read from Parse.

That is, as I think you now guessed, not really the best way to do it. It's much better to initiate the transition to the next scene, and if the image is not available, present a UIActivityIndicatorView (a spinner), retrieve the image, and when it's done, remove the spinner and show the image. But delaying for a fixed amount of time is not going to work well: Sometimes you'll make the user wait longer than needed; sometimes you won't have waited long enough. (And, of course, doing the request synchronously is invariably not the right approach.)

The implementation of this is probably simplified if you put this image retrieval code inside the destination view controller. To have one view controller initiate an asynchronous process and have another be notified of the completion is awkward (though can be done through judicious use of notifications). But in this example (where you don't know which image to retrieve until you select a row), I see little benefit.

Having said all of that, the code is initiating two asynchronous requests, one for Record and one for the image itself. I wonder if you could capture this Record information when you populate this initiate table view. That way you only have to retrieve the image. Now perhaps Parse does some caching and the retrieval of the Record is incredibly fast anyway (so benchmark it before you refactor the code), but if not, you might want to capture the PFFile objects when you populate the original table view, saving you from having to do two queries.

这篇关于如何在iOS中将解析读取的图像与屏幕显示同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆