在新的 collectionViewCell 中加载 selectedIndexItem(使 imageCache 无效)
load selectedIndexItem in new collectionViewCell (invalidate imageCache)
我在基于 collectionViewCell 的 selectedIndexPath 详细加载 CustomImageView: UIImageView 时遇到很多问题 viewController。我已成功传递并加载 UILabel 和 UITextView,但无法使用相同的过程和代码逻辑从相同的 selectedIndexPath 加载 CustomImageView:UIImageView。我相信它与清除或重置我的图像缓存有关,但不确定在何处或确切执行什么代码来执行此操作。对不起,任何多余的代码,只是想彻底。感谢您的帮助或指导!
// 模型对象 classes 存储来自 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
中的规划cellclass
class BasePlanningCell: BaseCell2 {
var currentPlanners = [CurrentPlanner]()
var currentPlanner: CurrentPlanner? {
didSet {
setupProfileImage()
}
}
fileprivate func setupProfileImage() {
if let profileImageUrl = currentPlanner?.profileImageUrl {
userProfileImageView.loadImageUsingCacheWithUrlString(profileImageUrl)
}
}
// 在第一个 collectionView 中点击单元格 class - 调用委托方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("cell tapped")
// cell delegate method called from collectionViewController
travelersFeedVC?.showPlanningViewDetailView(indexPath: indexPath)
}
// 第一个 collectionViewController class - 在 cell tap 上执行的方法
func showPlanningViewDetailView(indexPath: IndexPath) {
let plannersDetailVC = PlanningPlaceDetailsVC()
plannersDetailVC.profileImageUrl = plannedPlaces[indexPath.row].profileImageUrl!
print(plannersDetailVC.profileImageUrl!)
show(plannersDetailVC, sender: self)
}
// 第二个 DetailViewController class
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:
// ...
}
}
// 第二个 DetailViewControllers 单元格委托 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 class
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
}
我自己想出来的。也许不言自明,但我必须在我的 getProfileImageMethod(str : String) 中将 imageUrlString 转换回 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
}
我在基于 collectionViewCell 的 selectedIndexPath 详细加载 CustomImageView: UIImageView 时遇到很多问题 viewController。我已成功传递并加载 UILabel 和 UITextView,但无法使用相同的过程和代码逻辑从相同的 selectedIndexPath 加载 CustomImageView:UIImageView。我相信它与清除或重置我的图像缓存有关,但不确定在何处或确切执行什么代码来执行此操作。对不起,任何多余的代码,只是想彻底。感谢您的帮助或指导!
// 模型对象 classes 存储来自 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
中的规划cellclassclass BasePlanningCell: BaseCell2 {
var currentPlanners = [CurrentPlanner]()
var currentPlanner: CurrentPlanner? {
didSet {
setupProfileImage()
}
}
fileprivate func setupProfileImage() {
if let profileImageUrl = currentPlanner?.profileImageUrl {
userProfileImageView.loadImageUsingCacheWithUrlString(profileImageUrl)
}
}
// 在第一个 collectionView 中点击单元格 class - 调用委托方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("cell tapped")
// cell delegate method called from collectionViewController
travelersFeedVC?.showPlanningViewDetailView(indexPath: indexPath)
}
// 第一个 collectionViewController class - 在 cell tap 上执行的方法
func showPlanningViewDetailView(indexPath: IndexPath) {
let plannersDetailVC = PlanningPlaceDetailsVC()
plannersDetailVC.profileImageUrl = plannedPlaces[indexPath.row].profileImageUrl!
print(plannersDetailVC.profileImageUrl!)
show(plannersDetailVC, sender: self)
}
// 第二个 DetailViewController class
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:
// ...
}
}
// 第二个 DetailViewControllers 单元格委托 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 class
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
}
我自己想出来的。也许不言自明,但我必须在我的 getProfileImageMethod(str : String) 中将 imageUrlString 转换回 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
}