我有一个创建网格的UICollectionView。制作网格的每个单元格都有一个UIImage(在IB中创建)。
我正在使用可重复使用的单元来保持请求。 我怎样才能使用这个单元格和UIImage?在它消失之前,有没有将它存储在一个数组中?我创建了一个标签,但如果这有用,我不会这样做?如果我手动创建每个单元格,那么我的控制器中将有大约100个@IBOutlets!这是我的代码显示单元格..
任何想法都会很精彩。我试图在单元格内部获取UIImage,因此我可以隐藏它并在单元格出列之前命名它。
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("LetterCell", forIndexPath: indexPath) as UICollectionViewCell
cell.tag = indexPath.row
return cell
}
答案 0 :(得分:0)
图像占用了大量的内存。因此,您通常不希望架构要求您一次将所有图像(或更糟糕的是,单元格)保存在内存中。您希望重用您的集合视图单元格,并且您希望以即时方式从持久存储中检索图像(又名,"懒惰"图像加载)。
为了最大限度地减少应用程序的内存占用,因此您的模型通常会包含最少量的信息,例如只是对这些图像的引用(例如文件名)。仅在UI真正需要时才加载图像。
例如,假设图像是设备的Documents文件夹中的文件,那么您可能有一个文件名数组(在下面的示例中称为imageNames
),您可能会这样做类似的东西:
var imageNames = [String]() // this is populated elsewhere, perhaps `viewDidLoad`
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as CustomCell
let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let imageName = imageNames[indexPath.item]
let path = documentsFolder.stringByAppendingPathComponent(imageName)
let image = UIImage(contentsOfFile: path)
cell.imageView.image = image
return cell
}
如果您真的想要将这些图像保存在内存中(例如,为了更平滑的响应时间),您可以使用NSCache
,但请确保此缓存在接收内存压力时自行清空。例如:
var imageCache = ImageCache()
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as CustomCollectionViewCell
let imageName = imageNames[indexPath.item]
if let image = imageCache.objectForKey(imageName) as? UIImage {
cell.imageView.image = image
} else {
let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let path = documentsFolder.stringByAppendingPathComponent(imageName)
if let image = UIImage(contentsOfFile: path) {
imageCache.setObject(image, forKey: imageName)
cell.imageView.image = image
}
}
return cell
}
其中
class ImageCache : NSCache {
var observer: NSObjectProtocol!
override init() {
super.init()
// empty queue upon memory pressure
observer = NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidReceiveMemoryWarningNotification, object: nil, queue: NSOperationQueue.mainQueue()) { [unowned self] notification in
self.removeAllObjects()
}
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(observer)
}
}
还可以考虑其他优化措施。例如,如果这些图像很大,您可以确保重新加载图像视图,并将图像大小调整为最适合集合视图单元格的图像。但希望这能说明在处理UICollectionView
中的图像时的一些基本概念。