为什么我的图片下载后没有立即显示?
Why my image is not display immediately after downloaded?
我遇到异步问题 programming.I 有一个 UIScrollView
当我进入细节 view.So 时会显示多张图像 (3~10),我有两个过程当前工作 on.First,当我进入详细视图时,post 请求将调用 api 以显示详细数据(图像和数据)。其次,当我获取详细数据时,我必须再次下载来自数组的图像(带有 url 的图像)。
我不知道我的 code.And 有什么问题,我也是异步编程的新手。
我的问题是当我第一次进入 UIScrollView 时,它卡在了指示器上
http://puu.sh/ijggV/fa90d7baed.png
当我在下载了三张图片后再次进入 UITableViewCell 并进入 UIScrollView 时,
http://puu.sh/ijgkN/d356f521b7.png
是因为ViewWillAppear吗?
当我尝试 ViewDidLoad 时,即使我多次更改选项卡,图像也不会显示并卡在加载中
这是我的视图控制器
import UIKit
import Kingfisher
class SecondViewController: UIViewController,AuctionAPIProtocol{
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imageIndicator: UIActivityIndicatorView!
var api : AuctionAPI?
var preferredViews: [UIView]!
var detailData : [AuctionModel] = []
var images = [UIImage]()
override func viewWillAppear(animated: Bool) {
api = AuctionAPI(delegate: self)
super.viewWillAppear(true)
//let images = [UIImage(named: "Image1")!, UIImage(named: "Image2")!, UIImage(named: "Image3")!]
self.preferredViews = [UIView]()
if self.detailData.isEmpty{
self.imageIndicator?.center
self.imageIndicator?.startAnimating()
// Start call the api to get the detail data
self.getAuctionDetailPhotos()
println("Auction Call")
}
// When the api get the detail data and downloaded the images,the image will show in the scroll view
if images != []{
println("Condition 1 In")
let photos : [UIImage] = self.images
for image in photos {
let preferredView = UIView(frame: CGRectMake(0, 0, image.size.width, image.size.height))
let imageView = UIImageView(frame: CGRectMake(0, 0, image.size.width, image.size.height))
imageView.image = image
imageView.contentMode = .ScaleAspectFit
imageView.clipsToBounds = true
preferredView.setTranslatesAutoresizingMaskIntoConstraints(false)
imageView.setTranslatesAutoresizingMaskIntoConstraints(false)
preferredView.addSubview(imageView)
scrollView.addSubview(preferredView)
preferredViews.append(preferredView)
}
self.imageIndicator?.stopAnimating()
}
}
func getAuctionDetailPhotos(){
api?.getAuctionDetail()
}
// This is one of the method from AuctionAPIProtocol which will went into results using delegate after API Request done
func didGetTheDetail(results: NSDictionary) {
var detail : NSDictionary = results["body"] as! NSDictionary
dispatch_async(dispatch_get_main_queue(),{
self.detailData = AuctionModel.dictWithJSON(detail)
println("Auction Call Ended")
if !(self.detailData.isEmpty){
var urlString = self.detailData[0].images as [String]
for url in urlString {
let imageUrl = NSURL(string: url)
// This is image downloading library that i using now named Kingfisher
KingfisherManager.sharedManager.retrieveImageWithURL(imageUrl!, optionsInfo: nil,
progressBlock: nil, completionHandler: { (image, error, cacheType, imageURL) -> () in
if var dimage = image {
self.images.append(dimage)
println("Photo Download Completed")
//println(self.images)
} else {
println("Error Downloading images")
}
})
}
}
})
}
override func updateViewConstraints() {
super.updateViewConstraints()
if !(images.isEmpty){
println("Condtion 2 In")
var prevView: UIView? = nil
for preferredView in preferredViews {
let imageView = preferredView.subviews[0] as! UIImageView
preferredView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[imageView]|",
options: nil, metrics: nil, views: ["imageView": imageView]))
preferredView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[imageView]|",
options: nil, metrics: nil, views: ["imageView": imageView]))
if prevView == nil {
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[preferredView(==scrollView)]",
options: nil, metrics: nil, views: ["scrollView": scrollView, "preferredView": preferredView]))
} else {
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prevView][preferredView(==scrollView)]",
options: nil, metrics: nil, views: ["scrollView": scrollView, "prevView": prevView!, "preferredView": preferredView]))
}
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[preferredView(==scrollView)]",
options: nil, metrics: nil, views: ["scrollView": scrollView, "preferredView": preferredView]))
prevView = preferredView
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !(images.isEmpty){
println("Condition 3 In")
let contentWidth = CGFloat(preferredViews.count) * scrollView.bounds.width
let contentHeight = scrollView.bounds.height
scrollView.contentSize = CGSizeMake(contentWidth, contentHeight)
}
}
}
有什么帮助吗?我真的需要帮助。
您可能需要将当前在 viewWillAppear
中的 "if images != []{}" 块放入 Kingfisher 的下载完成处理程序中。由于您正在下载多张图片,dispatch group
将帮助您等待所有下载完成。
我不确定它是否适合你,但我根据你的代码做了一些小改动。你可以找到它 here.
我遇到异步问题 programming.I 有一个 UIScrollView
当我进入细节 view.So 时会显示多张图像 (3~10),我有两个过程当前工作 on.First,当我进入详细视图时,post 请求将调用 api 以显示详细数据(图像和数据)。其次,当我获取详细数据时,我必须再次下载来自数组的图像(带有 url 的图像)。
我不知道我的 code.And 有什么问题,我也是异步编程的新手。
我的问题是当我第一次进入 UIScrollView 时,它卡在了指示器上
http://puu.sh/ijggV/fa90d7baed.png
当我在下载了三张图片后再次进入 UITableViewCell 并进入 UIScrollView 时,
http://puu.sh/ijgkN/d356f521b7.png
是因为ViewWillAppear吗? 当我尝试 ViewDidLoad 时,即使我多次更改选项卡,图像也不会显示并卡在加载中
这是我的视图控制器
import UIKit
import Kingfisher
class SecondViewController: UIViewController,AuctionAPIProtocol{
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imageIndicator: UIActivityIndicatorView!
var api : AuctionAPI?
var preferredViews: [UIView]!
var detailData : [AuctionModel] = []
var images = [UIImage]()
override func viewWillAppear(animated: Bool) {
api = AuctionAPI(delegate: self)
super.viewWillAppear(true)
//let images = [UIImage(named: "Image1")!, UIImage(named: "Image2")!, UIImage(named: "Image3")!]
self.preferredViews = [UIView]()
if self.detailData.isEmpty{
self.imageIndicator?.center
self.imageIndicator?.startAnimating()
// Start call the api to get the detail data
self.getAuctionDetailPhotos()
println("Auction Call")
}
// When the api get the detail data and downloaded the images,the image will show in the scroll view
if images != []{
println("Condition 1 In")
let photos : [UIImage] = self.images
for image in photos {
let preferredView = UIView(frame: CGRectMake(0, 0, image.size.width, image.size.height))
let imageView = UIImageView(frame: CGRectMake(0, 0, image.size.width, image.size.height))
imageView.image = image
imageView.contentMode = .ScaleAspectFit
imageView.clipsToBounds = true
preferredView.setTranslatesAutoresizingMaskIntoConstraints(false)
imageView.setTranslatesAutoresizingMaskIntoConstraints(false)
preferredView.addSubview(imageView)
scrollView.addSubview(preferredView)
preferredViews.append(preferredView)
}
self.imageIndicator?.stopAnimating()
}
}
func getAuctionDetailPhotos(){
api?.getAuctionDetail()
}
// This is one of the method from AuctionAPIProtocol which will went into results using delegate after API Request done
func didGetTheDetail(results: NSDictionary) {
var detail : NSDictionary = results["body"] as! NSDictionary
dispatch_async(dispatch_get_main_queue(),{
self.detailData = AuctionModel.dictWithJSON(detail)
println("Auction Call Ended")
if !(self.detailData.isEmpty){
var urlString = self.detailData[0].images as [String]
for url in urlString {
let imageUrl = NSURL(string: url)
// This is image downloading library that i using now named Kingfisher
KingfisherManager.sharedManager.retrieveImageWithURL(imageUrl!, optionsInfo: nil,
progressBlock: nil, completionHandler: { (image, error, cacheType, imageURL) -> () in
if var dimage = image {
self.images.append(dimage)
println("Photo Download Completed")
//println(self.images)
} else {
println("Error Downloading images")
}
})
}
}
})
}
override func updateViewConstraints() {
super.updateViewConstraints()
if !(images.isEmpty){
println("Condtion 2 In")
var prevView: UIView? = nil
for preferredView in preferredViews {
let imageView = preferredView.subviews[0] as! UIImageView
preferredView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[imageView]|",
options: nil, metrics: nil, views: ["imageView": imageView]))
preferredView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[imageView]|",
options: nil, metrics: nil, views: ["imageView": imageView]))
if prevView == nil {
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[preferredView(==scrollView)]",
options: nil, metrics: nil, views: ["scrollView": scrollView, "preferredView": preferredView]))
} else {
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prevView][preferredView(==scrollView)]",
options: nil, metrics: nil, views: ["scrollView": scrollView, "prevView": prevView!, "preferredView": preferredView]))
}
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[preferredView(==scrollView)]",
options: nil, metrics: nil, views: ["scrollView": scrollView, "preferredView": preferredView]))
prevView = preferredView
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !(images.isEmpty){
println("Condition 3 In")
let contentWidth = CGFloat(preferredViews.count) * scrollView.bounds.width
let contentHeight = scrollView.bounds.height
scrollView.contentSize = CGSizeMake(contentWidth, contentHeight)
}
}
}
有什么帮助吗?我真的需要帮助。
您可能需要将当前在 viewWillAppear
中的 "if images != []{}" 块放入 Kingfisher 的下载完成处理程序中。由于您正在下载多张图片,dispatch group
将帮助您等待所有下载完成。
我不确定它是否适合你,但我根据你的代码做了一些小改动。你可以找到它 here.