Обновление Swift Firebase UICollectionView вызывает дублирование миниатюр - PullRequest
0 голосов
/ 11 мая 2018

Я пытался найти ответ на эту проблему, но не повезло.Когда я использую свой 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.Ниже приведены изображения того, что происходит.

enter image description here

enter image description here

1 Ответ

0 голосов
/ 11 мая 2018

В вашем методе cellForItemAt добавьте это, прежде чем запускать задачу по загрузке нового образа, и она будет работать.

cell.postImage.image = nil
cell.postImage.sd_cancelCurrentImageLoad()
...