在新collectionViewCell中加载selectedIndexItem(使imageCache无效)

时间:2017-07-07 00:45:13

标签: swift uiimageview uicollectionviewcell selecteditem image-caching

我在基于collectionViewCell的selectedIndexPath的详细viewController中加载CustomImageView:UIImageView时遇到了很多麻烦。我已经成功传递并加载了UILabels和UITextViews,但是无法使用相同的进程和代码逻辑从同一个selectedIndexPath加载CustomImageView:UIImageView。我认为它与清除或重置我的图像缓存有关,但不确定执行此操作的位置或确切执行的代码。对不起任何多余的代码,只是想彻底。感谢您的帮助或指导!

//存储来自Firebase的值的模型对象类

class CurrentPlanner: SafeJsonObjectPlanner {

    var name: String?
    var profileImageUrl: String?
    var planningPlace: String?

    init(dictionary: [String: AnyObject]) {
        self.name = dictionary["addedBy"] as? String
        self.profileImageUrl = dictionary["profileImageUrl"] as? String
        self.planningPlace = dictionary["planning"] as? String
    }
}

// CustomImageView:填充第一个collectionViewController的UIImageView扩展

let imageCache = NSCache<NSString, UIImage>()

class CustomImageView: UIImageView {

    var imageUrlString: String?

    func loadImageUsingUrlString(_ urlString: String) {

        imageUrlString = urlString
        let url = URL(string: urlString)
        image = nil

        if let imageFromCache = imageCache.object(forKey: urlString as NSString) {
            self.image = imageFromCache
            return
        }

        URLSession.shared.dataTask(with: url!, completionHandler: { (data, respones, error) in

            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async(execute: {
                let imageToCache = UIImage(data: data!)
                if self.imageUrlString == urlString {
                    self.image = imageToCache
                }
                imageCache.setObject(imageToCache!, forKey: urlString as NSString)
            })
        }).resume()
    }
}

extension UIImageView {
    func loadImageUsingCacheWithUrlString(_ urlString: String) {
        self.image = nil

        //check cache for image first
        if let cachedImage = imageCache.object(forKey: urlString as NSString) {
            self.image = cachedImage
            return
        }

        //otherwise fire off a new download
        let url = URL(string: urlString)
        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in

            //download hit an error so lets return out
            if let error = error {
                print(error)
                return
            }

            DispatchQueue.main.async(execute: {
                if let downloadedImage = UIImage(data: data!) {
                    imageCache.setObject(downloadedImage, forKey: urlString as NSString)
                    self.image = downloadedImage
                }
            })
        }).resume()
    }
}

//在第一个collectionView中计划单元格类

class BasePlanningCell: BaseCell2 {

    var currentPlanners = [CurrentPlanner]()

    var currentPlanner: CurrentPlanner? {
        didSet {
            setupProfileImage()
        }
    }

    fileprivate func setupProfileImage() {
        if let profileImageUrl = currentPlanner?.profileImageUrl {        
 userProfileImageView.loadImageUsingCacheWithUrlString(profileImageUrl)
        }
    }

//在第一个collectionView中调用单元格类 - 调用委托方法

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("cell tapped")
        // cell delegate method called from collectionViewController
        travelersFeedVC?.showPlanningViewDetailView(indexPath: indexPath)
    }

//第一个collectionViewController类 - 在单元格点击上执行的方法

    func showPlanningViewDetailView(indexPath: IndexPath) {
        let plannersDetailVC = PlanningPlaceDetailsVC()

        plannersDetailVC.profileImageUrl = plannedPlaces[indexPath.row].profileImageUrl!
        print(plannersDetailVC.profileImageUrl!)

        show(plannersDetailVC, sender: self)
    }

// 2nd DetailViewController类

    var nameString: String!
    var locationString: String!
    var profileImageUrl: String!

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        switch indexPath.item {
        case 0:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PlanningDetailViewCells", for: indexPath) as! PlanningDetailViewCells
            cell.myMethod(str: nameString)
            cell.getLocationMethod(str: locationString)
            cell.getProfileImageMethod(str: profileImageUrl)
            return cell
        case 1:
            // ...
        case 2:
             // ...
        default:
             // ...
        }
    }

// 2nd DetailViewControllers Cells Delegate Class

    func myMethod(str : String){
        nameString = str
        print("var : \(nameString)")
        planningCellHeader?.titleLabel.text = nameString
    }

    func getLocationMethod(str : String){
        locationString = str
        print("var : \(String(describing: locationString))")
        planningCellHeader?.locationTextView.text = locationString
    }

    func getProfileImageMethod(str : String){
        profileImageUrl = str
        print("var : \(String(describing: profileImageUrl))")
        planningCellHeader?.userProfileImageView.imageUrlString = profileImageUrl
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        switch indexPath.section {
        case 0:
            switch indexPath.item {
            case 0:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "headerId", for: indexPath) as! PlanningCellHeader                
                cell.myMethod(str: nameString)
                cell.getLocationMethod(str: locationString)
                cell.getProfileImageMethod(str: profileImageUrl)
                return cell
            case 1:
                // ...
            default:
                // ...
            }
        default:
            // ...
        }
    }

//保存视图的headerCell类

var nameString: String?
var locationString: String?
var profileImageUrl: String?

    let titleLabel: UILabel = {
        let label = UILabel()
        // ...
        return label
    }()

    let locationTextView: UITextView = {
        let textView = UITextView()
        // ...
        return textView
    }()

    let userProfileImageView: CustomImageView = {
        let imageView = CustomImageView()
        // ...
        return imageView
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        titleLabel.text = nameString
        locationTextView.text = locationString
        userProfileImageView.imageUrlString = profileImageUrl
        setupViews()
    }
        func myMethod(str : String){
        nameString = str
        print("var : \(String(describing: nameString))")
        titleLabel.text = nameString
    }

    func getLocationMethod(str : String){
        locationString = str
        print("var : \(String(describing: locationString))")
        locationTextView.text = locationString
    }

    func getProfileImageMethod(str : String){
        profileImageUrl = str
        print("var : \(String(describing: profileImageUrl))")
//        userProfileImageView.image = UIImage(named: "meAndDuncan")
        userProfileImageView.imageUrlString = profileImageUrl
    }

1 个答案:

答案 0 :(得分:0)

我自己想通了。也许是自我解释,但我必须将imageUrlString转换回我的getProfileImageMethod(str:String)中的Data(contentsOf:url!),如下所示:

func getProfileImageMethod(str : String){
    profileImageUrl = str
    print("var : \(String(describing: profileImageUrl))")
    // added the code below and it worked!
    var imageUrlString: String?
    imageUrlString = profileImageUrl
    let url = URL(string: imageUrlString!)
    let data = try? Data(contentsOf: url!)
    let image: UIImage = UIImage(data: data!)!

    userProfileImageView.image = image
}