我想使用UICollectionView
来显示图像,我通过api调用获取图像。
问题:所以我通过api调用获取图像路径,以便如何将其显示到UICollectionView
??
这是我的代码::
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary
let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell
cell.imagev.image = dic["image"] as? UIImage
return cell
}
这是我的api回复
(
{
image = "http://radio.spainmedia.es/wp-content/uploads/2015/12/esquire.jpg";
slug = esquire;
},
{
image = "http://radio.spainmedia.es/wp-content/uploads/2015/12/forbes.jpg";
slug = forbes;
},
{
image = "http://radio.spainmedia.es/wp-content/uploads/2015/12/tapas.jpg";
slug = tapas;
}
)
所以如何在我的UICollectionView
UPDATE ::使用注释代码变得奇怪的问题我在viewdidload中调用我的webservice
override func viewDidLoad() {
super.viewDidLoad()
webimages()
// Do any additional setup after loading the view, typically from a nib.
}
并开始调用webservice
func webimages()
{
let url = "http://radio.spainmedia.es/podcasts/"
request(.GET, url, parameters: nil, encoding: .JSON).responseJSON { (response:Response<AnyObject, NSError>) -> Void in
print(response.result.value)
self.imagearray = (response.result.value) as! NSMutableArray
print(self.imagearray)
}
}
但在请求它之后突然转到cellForItemAtIndexPath所以我的“imagearray”在那里找到了nil。然后它回归webimages()并给我api响应。
那我怎么解决这个问题呢?
我们有字符串数组我们在这里传递单个字符串所以你能告诉我什么是解决方案
答案 0 :(得分:2)
您正在将URL字符串设置为UIImage。首先必须先从该URL检索图像。使用以下方法快速解决问题:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell
if imagearray.count > 0
{
let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary
let imgURL: NSString = dic!["image"] as! NSString //Get URL string
let url = NSURL.URLWithString(imgURL); //Create URL
var err: NSError?
var imageData :NSData = NSData(contentsOfURL: url, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)! //Fetch Image Data
var cellImage = UIImage(data:imageData) //Create UIImage from Image data
cell.imagev.image = cellImage //Set image
}
return cell
}
请注意,这是在同步调用中获取图像URL的内容,因此在下载完成之前会冻结您的UI。此外,这不是缓存图像,因此当您滚动并重新创建单元格时,将一次又一次地下载图像。为了避免这种情况,我建议使用缓存。
为了获得更好的结果,这是异步加载图像的方式,不会冻结UI并缓存图像以避免网络负载。
首先必须首先创建一个类:
class ImageLoader {
var cache = NSCache() //Create cache
class var sharedLoader : ImageLoader {
struct Static {
static let instance : ImageLoader = ImageLoader()
}
return Static.instance
}
func imageForUrl(urlString: String , indexPathArg:NSIndexPath!, completionHandler:(image: UIImage?, url: String,indexPathResponse:NSIndexPath?) -> ()) {
let currentIndexPath: NSIndexPath! = indexPathArg.mutableCopy() as! NSIndexPath
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
let data: NSData? = self.cache.objectForKey(urlString) as? NSData
//Check if image data for this URL already exists in Cache
if let goodData = data {
//data exists, no need to download it again. Just send it
let image = UIImage(data: goodData)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString,indexPathResponse: currentIndexPath)
})
return
}
//Data does not exist, We have to download it
let downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!,completionHandler: { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in
if (error != nil) {
//Download failed
completionHandler(image: nil, url: urlString, indexPathResponse: currentIndexPath)
return
}
if data != nil {
//Download successful,Lets save this downloaded data to our Cache and send it forward as UIImage
let image = UIImage(data: data!)
self.cache.setObject(data!, forKey: urlString)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString, indexPathResponse: currentIndexPath)
})
return
}
})
downloadTask.resume()
})
}
}
然后你必须修改你的collectionview委托:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell
if imagearray.count > 0
{
let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary
let imgURL: NSString = dic!["image"] as! NSString//Get URL string
ImageLoader.sharedLoader.imageForUrl(imgURL as String,indexPathArg: indexPath, completionHandler:{(image: UIImage?, url: String, indexPathResponse: NSIndexPath?) in
let indexArr:NSArray = collectionView!.indexPathsForVisibleItems()
if indexArr.containsObject(indexPathResponse!)
{
cell.imagev.image = image //Set image
}
})
}
return cell
}
现在它将异步加载您的图像,并仅在必要时下载它。巨大的成功! (引用波拉特)。我添加了评论,以便您可以了解我的代码和Daniel的代码中发生了什么:)
修复您的崩溃问题,这不是您原始问题的一部分,而是您创建的另一个问题,将部分中的项目的计数返回到您的图像数组的计数,并在检索到数据后重新加载集合视图:
func webimages()
{
let url = "http://radio.spainmedia.es/podcasts/"
request(.GET, url, parameters: nil, encoding: .JSON).responseJSON { (response:Response<AnyObject, NSError>) -> Void in
print(response.result.value)
self.imagearray = (response.result.value) as! NSMutableArray
print(self.imagearray)
//Reload Collection view
self.collectionView?.reloadData()
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagearray.count
}
Imageloader课程的学分:Daniel Sattler
特别感谢:CouchDeveloper
答案 1 :(得分:0)
您可以轻松地从该网址下载图片并将其设置为图片视图的图片,
试试这个,https://github.com/natelyman/SwiftImageLoader
将ImageLoader类添加到项目中并修改collectionview数据源,如下所示
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary
let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell
//cell.imagev.image = dic["image"] as? UIImage
ImageLoader.sharedLoader.imageForUrl(dic["image"], completionHandler: {(image: UIImage?, url: String) in
cell.imagev.image = image
})
return cell
}
这是一个异步图像加载类,因此如果您反对使用任何第三方库或类,UI不会冻结或给您任何其他问题,请手动执行@NSNoob的答案。
其他好的图像加载库是
https://github.com/nicklockwood/AsyncImageView
https://github.com/onevcat/Kingfisher
https://github.com/MengTo/Spring/blob/master/Spring/AsyncImageView.swift
答案 2 :(得分:0)
您可以按照以下方式扩展UIImageView -
extension UIImageView {
public func imageFromU(urlString: String) {
if let url = NSURL(string: urlString) {
let request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
(response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
if let imageData = data as NSData? {
self.image = UIImage(data: imageData)
}
}
}
}
}
然后在任何UIImageView中你将有一个非常简单的帮助方法,如下所示 -
yourImageView.imageFromURL("https://yoururl.com/image.png")
在你的情况下
cell.imagev.image.imageFromURL(dic["image"])
答案 3 :(得分:0)
if let url = NSURL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
if let data = NSData(contentsOfURL: url){
imageURL!.contentMode = UIViewContentMode.ScaleAspectFit
imageURL!.image = UIImage(data: data)
}
}