在控制台中,有空imageArray的打印,但是我正在downloadImages函数中下载它。在模拟器中,图片将不会加载
import UIKit
import PinterestLayout
import ProgressHUD
class MainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet weak var collectionView: UICollectionView!
var postsArray = [Post]()
var imagesArray = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
if let layout = collectionView.collectionViewLayout as? PinterestLayout {
layout.delegate = self
}
collectionView.contentInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
loadItems()
downloadPhoto()
}
func loadItems() {
ref.child("Posts").observe(.childAdded) { (snapshot) in
let snapshotValue = snapshot.value as! Dictionary<String,Any>
if let title = snapshotValue["title"], let price = snapshotValue["price"], let downloadUrl = snapshotValue["downloadUrl"], let category = snapshotValue["category"], let senderUid = snapshotValue["senderUid"] {
let post = Post()
post.title = title as! String
post.price = price as! String
post.downloadUrl = downloadUrl as! String
post.category = category as! String
post.senderUid = senderUid as! String
self.postsArray.append(post)
self.collectionView.reloadData()
}
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tabBarController?.tabBar.shadowImage = UIImage()
tabBarController?.tabBar.backgroundImage = UIImage()
}
func downloadPhoto(){
DispatchQueue.global().async {
self.imagesArray.removeAll() // this is the image array
for i in 0..<self.postsArray.count {
guard let url = URL(string: self.postsArray[i].downloadUrl) else {
continue
}
let group = DispatchGroup()
print(url)
print("-------GROUP ENTER-------")
group.enter()
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
print(response?.suggestedFilename ?? url.lastPathComponent)
if let imgData = data, let image = UIImage(data: imgData) {
DispatchQueue.main.async() {
self.imagesArray.append(image)
self.collectionView.reloadData()
}
} else if let error = error {
print(error)
}
group.leave()
}).resume()
group.wait()
}
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagesArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mainCell", for: indexPath) as! MainCollectionViewCell
cell.imgView.downloadImage(from: self.postsArray[indexPath.row].downloadUrl)
return cell
}
}
extension MainViewController: PinterestLayoutDelegate {
func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat {
let image = imagesArray[indexPath.item]
let height = image.size.height
return height
}
}
extension UIImageView {
func downloadImage(from url: String){
let urlRequest = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: urlRequest) {
(data,response,error) in
if error != nil {
print(error ?? error!)
return
}
if let data = data {
DispatchQueue.main.async {
self.image = UIImage(data: data)
}
}
}
task.resume()
}
}
更新的代码:
import UIKit
import PinterestLayout
import ProgressHUD
import Kingfisher
class MainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet weak var collectionView: UICollectionView!
var postsArray = [Post]()
var imagesArray = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
if let layout = collectionView.collectionViewLayout as? PinterestLayout {
layout.delegate = self
}
collectionView.contentInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
loadItems()
collectionView.reloadData()
}
func loadItems() {
ref.child("Posts").observe(.childAdded) { (snapshot) in
let snapshotValue = snapshot.value as! Dictionary<String,Any>
if let title = snapshotValue["title"], let price = snapshotValue["price"], let downloadUrl = snapshotValue["downloadUrl"], let category = snapshotValue["category"], let senderUid = snapshotValue["senderUid"] {
let post = Post()
post.title = title as! String
post.price = price as! String
post.downloadUrl = downloadUrl as! String
post.category = category as! String
post.senderUid = senderUid as! String
self.postsArray.append(post)
self.downloadPhoto()
print(self.imagesArray.count)
self.collectionView.reloadData()
}
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tabBarController?.tabBar.shadowImage = UIImage()
tabBarController?.tabBar.backgroundImage = UIImage()
}
func downloadPhoto(){
DispatchQueue.global().async {
self.imagesArray.removeAll() // this is the image array
for i in 0..<self.postsArray.count {
guard let url = URL(string: self.postsArray[i].downloadUrl) else {
continue
}
let group = DispatchGroup()
print(url)
print("-------GROUP ENTER-------")
group.enter()
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
print(response?.suggestedFilename ?? url.lastPathComponent)
if let imgData = data, let image = UIImage(data: imgData) {
DispatchQueue.main.async() {
self.imagesArray.append(image)
let post = Post()
post.image = image
self.collectionView.reloadData()
}
} else if let error = error {
print(error)
}
group.leave()
}).resume()
group.wait()
}
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return postsArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mainCell", for: indexPath) as! MainCollectionViewCell
let resource = ImageResource(downloadURL: URL(string: postsArray[indexPath.row].downloadUrl)!, cacheKey: postsArray[indexPath.row].downloadUrl)
cell.imgView.kf.setImage(with: resource)
return cell
}
}
extension MainViewController: PinterestLayoutDelegate {
func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat {
let image = imagesArray[indexPath.row]
let height = image.size.height / 6
return height
}
}
//AND POST CLASS
import UIKit
class Post {
var title : String = ""
var category : String = ""
var downloadUrl : String = ""
var price : String = ""
var senderUid : String = ""
var image = UIImage()
}
答案 0 :(得分:0)
您需要致电
downloadPhoto()
内部
loadItems()
因为两者都是异步的,在这里
self.postsArray.append(post)
downloadPhoto()
注意:我建议在下载图像之前先检查一下缓存,或更好地使用SDWebImage
答案 1 :(得分:0)
正如Sh_Khan所说,您需要在downloadPhoto
完成后致电loadItems
,否则将没有任何帖子可以循环播放。
此外,这里还有几点要考虑...
我更喜欢使用KingFisher来下载和缓存图像,该库已经为您管理了其中的大部分操作,使您可以专注于应用程序。
如果您不想使用一个库,类似的东西应该会帮助您...
var imageCache = [String: UIImage]()
func downloadImage(from url: String){
if let image = imageCache[url] as? UIImage {
self.image = image
return
}
let urlRequest = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: urlRequest) {
(data,response,error) in
if error != nil {
print(error ?? error!)
return
}
if let data = data {
DispatchQueue.main.async {
let image = UIImage(data: data)
imageCache[url] = image
self.image = image
}
}
}
task.resume()
}
Kingfisher示例:
imageView.kf.setImage(with: url, completionHandler: {
(image, error, cacheType, imageUrl) in
// image: Image? `nil` means failed
// error: NSError? non-`nil` means failed
// cacheType: CacheType
// .none - Just downloaded
// .memory - Got from memory cache
// .disk - Got from disk cache
// imageUrl: URL of the image
})
所以有一个postsArray和images数组
var postsArray = [Post]()
var images = [String: UIImage]() // dictionary, maps url to image
然后,当您收到帖子时:
let post = Post()
post.title = title as! String
post.price = price as! String
post.downloadUrl = downloadUrl as! String
post.category = category as! String
post.senderUid = senderUid as! String
self.postsArray.append(post)
imageView.kf.setImage(with: url, completionHandler: { (image, error, cacheType, imageUrl) in
// check image is not nil etc
images[url] = image
collectionView.reloadData()
}
CellForRowAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mainCell", for: indexPath) as! MainCollectionViewCell
cell.imgView.image = images[postsArray[indexPath.row].downloadUrl]
return cell
}