Я пытался найти ответ на эту проблему, но не повезло.Когда я использую свой refreshcontrol, мои UICollectionView Cells начинают повторять / дублировать ячейки.Миниатюры начинают переключаться всякий раз, когда я начинаю обновлять UICollectionView.
import UIKit
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var postImage: UIImageView!
override func prepareForReuse() {
self.postImage.image = nil
super.prepareForReuse()
}
}
Я уже добавил prepareForReuse для UICollectionViewCellно не повезло.
import UIKit
import Firebase
import SVProgressHUD
import SDWebImage
import SwiftyJSON
import CoreLocation
class CollectionView: UICollectionViewController, UICollectionViewDelegateFlowLayout, CLLocationManagerDelegate {
@IBOutlet var collectionViews: UICollectionView!
var posts = [Post]()
var uid: String?
let user = Auth.auth().currentUser?.uid
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
locationManager.delegate = self
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
locationManager.stopUpdatingLocation()
collectionViews.dataSource = self
collectionViews.delegate = self
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .notDetermined, .restricted, .denied:
print("No access")
downloadImagesWithoutLocation(refreshing: false, refreshControl: nil)
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
downloadImages(refreshing: false, refreshControl: nil)
}
} else {
print("Location services are not enabled")
}
// refresh control
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshControlAction(refreshControl:)), for: UIControlEvents.valueChanged)
self.collectionViews.insertSubview(refreshControl, at: 0)
}
@objc func refreshControlAction(refreshControl: UIRefreshControl) {
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .notDetermined, .restricted, .denied:
print("No access")
downloadImagesWithoutLocation(refreshing: true, refreshControl: refreshControl)
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
downloadImages(refreshing: true, refreshControl: refreshControl)
}
} else {
print("Location services are not enabled")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func downloadImagesWithoutLocation(refreshing: Bool, refreshControl: UIRefreshControl?) {
let ref = Database.database().reference().child("posts")
MBProgressHUD.showAdded(to: self.view, animated: true)
ref.queryOrdered(byChild: "businessName").observe(.childAdded, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
self.posts = []
for item in dict {
let json = JSON(item.value)
let uid = json["uid"].stringValue
var name: String = json["businessName"].stringValue
let address: String = json["businessStreet"].stringValue
let state: String = json["businessCity"].stringValue
let caption: String = json["caption"].stringValue
let downloadURL: String = json["download_url"].stringValue
let timestamp = json["timestamp"].doubleValue
let date = Date(timeIntervalSince1970: timestamp/1000)
let postID: String = json["postID"].stringValue
//let lat = json["businessLatitude"].doubleValue
//let long = json["businessLongitude"].doubleValue
//let businessLocation = CLLocation(latitude: lat, longitude: long)
//let latitude = self.locationManager.location?.coordinate.latitude
//let longitude = self.locationManager.location?.coordinate.longitude
//let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)
//let distanceInMeters: Double = userLocation.distance(from: businessLocation)
//let distanceInMiles: Double = distanceInMeters * 0.00062137
//let distanceLabelText = String(format: "%.2f miles away", distanceInMiles)
let distanceLabelText = "Not Available"
let usersReference = Database.database().reference(withPath: "users").queryOrderedByKey().queryEqual(toValue: uid)
usersReference.observeSingleEvent(of: .value, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
let userInfo = dict.allValues[0]
let userJSON = JSON(userInfo)
name = userJSON["name"].stringValue
}
let post = Post(uid: uid, caption: caption, downloadURL: downloadURL, name: name, date: date, address: address, state: state, distance: distanceLabelText, postID: postID)
self.posts.append(post)
//self.posts.sort {$0.distance.compare($1.distance) == .orderedAscending}
self.posts.sort {$0.date.compare($1.date) == .orderedAscending}
self.collectionViews.reloadData()
})
}
}
if refreshing {
refreshControl?.endRefreshing()
}
MBProgressHUD.hide(for: self.view, animated: true)
})
}
func downloadImages(refreshing: Bool, refreshControl: UIRefreshControl?) {
let ref = Database.database().reference().child("posts")
MBProgressHUD.showAdded(to: self.view, animated: true)
ref.queryOrdered(byChild: "businessName").observe(.childAdded, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
self.posts = []
for item in dict {
let json = JSON(item.value)
let uid = json["uid"].stringValue
var name: String = json["businessName"].stringValue
let address: String = json["businessStreet"].stringValue
let state: String = json["businessCity"].stringValue
let caption: String = json["caption"].stringValue
let downloadURL: String = json["download_url"].stringValue
let timestamp = json["timestamp"].doubleValue
let date = Date(timeIntervalSince1970: timestamp/1000)
let postID: String = json["postID"].stringValue
let lat = json["businessLatitude"].doubleValue
let long = json["businessLongitude"].doubleValue
let businessLocation = CLLocation(latitude: lat, longitude: long)
let latitude = self.locationManager.location?.coordinate.latitude
let longitude = self.locationManager.location?.coordinate.longitude
let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)
let distanceInMeters: Double = userLocation.distance(from: businessLocation)
let distanceInMiles: Double = distanceInMeters * 0.00062137
let distanceLabelText = String(format: "%.2f miles away", distanceInMiles)
//let distanceLabelText = "Not Available"
let usersReference = Database.database().reference(withPath: "users").queryOrderedByKey().queryEqual(toValue: uid)
usersReference.observeSingleEvent(of: .value, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
let userInfo = dict.allValues[0]
let userJSON = JSON(userInfo)
name = userJSON["name"].stringValue
}
let post = Post(uid: uid, caption: caption, downloadURL: downloadURL, name: name, date: date, address: address, state: state, distance: distanceLabelText, postID: postID)
self.posts.append(post)
self.posts.sort {$0.distance.compare($1.distance) == .orderedAscending}
self.collectionViews.reloadData()
})
}
}
if refreshing {
refreshControl?.endRefreshing()
}
MBProgressHUD.hide(for: self.view, animated: true)
})
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.postImage.image = nil
if self.posts[indexPath.row].downloadURL != nil {
cell.postImage.downloadImagezzz(from: self.posts[indexPath.row].downloadURL)
} else {
print("\n \(indexPath.row) could not return a value for pathToImage256 from Post. \n")
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 2
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.size.width / 3 - 1, height: collectionView.frame.size.width / 3 - 1)
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "PostSegue", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "PostSegue") {
let selectedCell = sender as! NSIndexPath
let selectedRow = selectedCell.row
let imagePage = segue.destination as! CollectionViewFeed
let user = self.posts[selectedRow].uid
imagePage.seguePostID = self.posts[selectedRow].downloadURL
imagePage.otherUser = user
print(self.posts[selectedRow].downloadURL)
} else {
print("\n Segue with identifier (imagePage) not found. \n")
}
}
}
extension UIImageView {
func downloadImagezzz(from imgURL: String) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) {
(data, responds, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}
Вот весь мой контроллер представления, который загружает UICollectionView.Ниже приведены изображения того, что происходит.