UICollectionView CustomCell 重用
UICollectionView CustomCell ReUse
我正在获取用户的 Photo Asset
并尝试在我的 UICollectionView
中创建自定义 UICollectionViewCell
,其中第一个索引是 Camera Image
,其他单元格是相机图像.但是当我滚动时,就像重新创建了索引处的图像,我注意到单元格中的一些图像得到了我在 index[0]
添加的视图
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
//Deque an GridViewCell
let cell: GridViewCell = (collectionView.dequeueReusableCellWithReuseIdentifier(CellReuseIdentifier, forIndexPath: indexPath) as? GridViewCell)!
if indexPath.item != 0 {
let asset = assetsFetchResults[indexPath.item - 1] as! PHAsset
cell.representedAssetIdentifier = asset.localIdentifier
imageManager.requestImageForAsset(asset, targetSize: AssetGridThumbnailSize, contentMode: PHImageContentMode.AspectFill, options: nil) { (result: UIImage?, info: [NSObject : AnyObject]?) -> Void in
//print(result)
if cell.representedAssetIdentifier.isEqualToString(asset.localIdentifier) {
if let imageResult = result {
cell.imageView.image = imageResult
}
}
}
} else {
let cameraButton = UIButton(frame: CGRectMake(0,0,80,80))
cameraButton.setTitle("Camera", forState: .Normal)
cameraButton.frame = cell.imageView.bounds
cell.imageView.addSubview(cameraButton)
}
return cell
}
下图为说明
可重复使用的单元格在滚动到视图外时会被集合视图重复使用,以防止大量内存使用。当某个单元格滚动到视图之外时,集合视图会将它们标记为可重用。可重用的单元格将被集合视图重用,而不是创建新的单元格。这将显着减少内存使用。如果同时只有 20 个单元格适合屏幕,为什么要在内存中保留 1000 个单元格。
因为单元格被重用,它们仍然会包含前一个单元格的内容,这意味着单元格仍然有 cameraButton 作为子视图。与图像相同的故事,您需要手动将它们从单元格中删除,并确保替换或删除所有旧内容。
当您执行将图像下载并在一段时间后设置到单元格的方法时,该单元格可能仍包含前一个单元格的图像。您应该清除 cellForRowAtIndexPath 方法开头的图像以删除旧的 image/subviews.
参见下面的示例:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! GridViewCell
if indexPath.row == 0 {
// Show the title becouse it's the first cell.
cell.titleLabel.hidden = false
// Title needs to be set in storyboard
// Default image for camera roll needs to be set in storyboard
} else {
// All the other cells.
cell.titleLabel.hidden = true
// Clear old content
cell.imageView.image = nil
// I don't exactly know what all this code does behind the screen, but I assume it's a method that downloads the image and add it to the imageView when it's done.
let asset = assetsFetchResults[indexPath.item - 1] as! PHAsset
cell.representedAssetIdentifier = asset.localIdentifier
imageManager.requestImageForAsset(asset, targetSize: AssetGridThumbnailSize, contentMode: PHImageContentMode.AspectFill, options: nil) { (result: UIImage?, info: [NSObject : AnyObject]?) -> Void in
//print(result)
if cell.representedAssetIdentifier.isEqualToString(asset.localIdentifier) {
if let imageResult = result {
cell.imageView.image = imageResult
}
}
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// Cell that needs to open the camera roll when tapped)
if indexPath.row == 0 {
// Do something that opens the camera roll
}
}
我没有测试这段代码,但它应该与此类似。
我正在获取用户的 Photo Asset
并尝试在我的 UICollectionView
中创建自定义 UICollectionViewCell
,其中第一个索引是 Camera Image
,其他单元格是相机图像.但是当我滚动时,就像重新创建了索引处的图像,我注意到单元格中的一些图像得到了我在 index[0]
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
//Deque an GridViewCell
let cell: GridViewCell = (collectionView.dequeueReusableCellWithReuseIdentifier(CellReuseIdentifier, forIndexPath: indexPath) as? GridViewCell)!
if indexPath.item != 0 {
let asset = assetsFetchResults[indexPath.item - 1] as! PHAsset
cell.representedAssetIdentifier = asset.localIdentifier
imageManager.requestImageForAsset(asset, targetSize: AssetGridThumbnailSize, contentMode: PHImageContentMode.AspectFill, options: nil) { (result: UIImage?, info: [NSObject : AnyObject]?) -> Void in
//print(result)
if cell.representedAssetIdentifier.isEqualToString(asset.localIdentifier) {
if let imageResult = result {
cell.imageView.image = imageResult
}
}
}
} else {
let cameraButton = UIButton(frame: CGRectMake(0,0,80,80))
cameraButton.setTitle("Camera", forState: .Normal)
cameraButton.frame = cell.imageView.bounds
cell.imageView.addSubview(cameraButton)
}
return cell
}
下图为说明
可重复使用的单元格在滚动到视图外时会被集合视图重复使用,以防止大量内存使用。当某个单元格滚动到视图之外时,集合视图会将它们标记为可重用。可重用的单元格将被集合视图重用,而不是创建新的单元格。这将显着减少内存使用。如果同时只有 20 个单元格适合屏幕,为什么要在内存中保留 1000 个单元格。
因为单元格被重用,它们仍然会包含前一个单元格的内容,这意味着单元格仍然有 cameraButton 作为子视图。与图像相同的故事,您需要手动将它们从单元格中删除,并确保替换或删除所有旧内容。
当您执行将图像下载并在一段时间后设置到单元格的方法时,该单元格可能仍包含前一个单元格的图像。您应该清除 cellForRowAtIndexPath 方法开头的图像以删除旧的 image/subviews.
参见下面的示例:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! GridViewCell
if indexPath.row == 0 {
// Show the title becouse it's the first cell.
cell.titleLabel.hidden = false
// Title needs to be set in storyboard
// Default image for camera roll needs to be set in storyboard
} else {
// All the other cells.
cell.titleLabel.hidden = true
// Clear old content
cell.imageView.image = nil
// I don't exactly know what all this code does behind the screen, but I assume it's a method that downloads the image and add it to the imageView when it's done.
let asset = assetsFetchResults[indexPath.item - 1] as! PHAsset
cell.representedAssetIdentifier = asset.localIdentifier
imageManager.requestImageForAsset(asset, targetSize: AssetGridThumbnailSize, contentMode: PHImageContentMode.AspectFill, options: nil) { (result: UIImage?, info: [NSObject : AnyObject]?) -> Void in
//print(result)
if cell.representedAssetIdentifier.isEqualToString(asset.localIdentifier) {
if let imageResult = result {
cell.imageView.image = imageResult
}
}
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// Cell that needs to open the camera roll when tapped)
if indexPath.row == 0 {
// Do something that opens the camera roll
}
}
我没有测试这段代码,但它应该与此类似。