gpt4 book ai didi

ios - Swift 2 reloadData 向 UICollectionView 添加了更多单元格

转载 作者:行者123 更新时间:2023-12-01 20:09:46 25 4
gpt4 key购买 nike

我的应用程序中有一个烦人的错误,每次我加载 UICollectionView Controller ,它复制单元格。

所以这是第一次加载 Collection View 的时间:

enter image description here

我有 2 个 View Controller ,所以这是第二个 View Controller 。如果我回到第一个 View Controller ,它只有一个按钮到第二个 View Controller ,然后再次转到触发 reloadData 函数的第二个 View Controller ,就会发生这种情况:

enter image description here

我不太确定为什么会这样,我正在使用 Todd Kramer 的 UICollectionView带有缓存图像:http://www.tekramer.com/downloading-images-asynchronously-in-swift-with-alamofire/唯一的区别是我从 JSON 异步加载图像 url 和数据,而不是像教程那样在模型或 plist 中静态定义。

以下是我在代码中所做更改的类:

import UIKit
import SwiftyJSON

private let PhotoCollectionViewCellIdentifier = "cell"

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

@IBOutlet weak var collectionView: UICollectionView!

var index: NSIndexPath!

var names = [String]()
var imgsUrl = [String]()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

let photo = PhotosDataManager()
let api = Api()

api.loadJsonData(self.names, imgsUrl: self.imgsUrl, batch: "2016", dept: "dafa") { names, imgsUrl in
self.names = names
self.imgsUrl = imgsUrl
photo.allPhotos(self.names, imgUrls: self.imgsUrl)
self.collectionView.reloadData()
}
}

@IBAction func button(sender: UIButton) {
NSNotificationCenter.defaultCenter().postNotificationName("alert1", object: self, userInfo: nil)
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

return PhotosDataManager.sharedManager.allPhotos(self.names, imgUrls: self.imgsUrl).count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoCollectionViewCellIdentifier, forIndexPath: indexPath) as! CollectionViewCell
dispatch_async(dispatch_get_main_queue(), {
cell.configure(self.glacierScenicAtIndex(indexPath))
})

return cell
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
PhotosDataManager.sharedManager.purgeCache()
self.performSegueWithIdentifier("previousViewController", sender: self)

}

func glacierScenicAtIndex(indexPath: NSIndexPath) -> GlacierScenic {
let photos = PhotosDataManager.sharedManager.allPhotos(self.names, imgUrls: self.imgsUrl)
return photos[indexPath.row]
}

}
class PhotosDataManager {

static let sharedManager = PhotosDataManager()
private var photos = [GlacierScenic]()

let decoder = ImageDecoder()
let photoCache = AutoPurgingImageCache(
memoryCapacity: 100 * 1024 * 1024,
preferredMemoryUsageAfterPurge: 60 * 1024 * 1024
)

func allPhotos(names: [String], imgUrls: [String]) -> [GlacierScenic] {

var glacierScenic: GlacierScenic!

for i in 0 ..< names.count {
glacierScenic = GlacierScenic(name: names[i], photoURLString: imgUrls[i])
photos.append(glacierScenic)
}

return photos
}

func getNetworkImage(urlString: String, completion: (UIImage -> Void)) -> (ImageRequest) {
let queue = decoder.queue.underlyingQueue
let request = Alamofire.request(.GET, urlString)
let imageRequest = ImageRequest(request: request)
imageRequest.request.response(
queue: queue,
responseSerializer: Request.imageResponseSerializer(),
completionHandler: { response in
guard let image = response.result.value else {
return
}
let decodeOperation = self.decodeImage(image) { image in
completion(image)
self.cacheImage(image, urlString: urlString)
}
imageRequest.decodeOperation = decodeOperation
}
)
return imageRequest
}

func decodeImage(image: UIImage, completion: (UIImage -> Void)) -> DecodeOperation {
let decodeOperation = DecodeOperation(image: image, decoder: self.decoder, completion: completion)
self.decoder.queue.addOperation(decodeOperation)
return decodeOperation
}

func cacheImage(image: Image, urlString: String) {
photoCache.addImage(image, withIdentifier: urlString)
}

func cachedImage(urlString: String) -> Image? {
return photoCache.imageWithIdentifier(urlString)
}

func purgeCache() {
// photoCache.removeAllImages()
print("memory used: \(photoCache.memoryUsage)")
}

}
class PhotosDataManager {

static let sharedManager = PhotosDataManager()
private var photos = [GlacierScenic]()

let decoder = ImageDecoder()
let photoCache = AutoPurgingImageCache(
memoryCapacity: 100 * 1024 * 1024,
preferredMemoryUsageAfterPurge: 60 * 1024 * 1024
)

func allPhotos(names: [String], imgUrls: [String]) -> [GlacierScenic] {

var glacierScenic: GlacierScenic!

for i in 0 ..< names.count {
glacierScenic = GlacierScenic(name: names[i], photoURLString: imgUrls[i])
photos.append(glacierScenic)
}

return photos
}

func getNetworkImage(urlString: String, completion: (UIImage -> Void)) -> (ImageRequest) {
let queue = decoder.queue.underlyingQueue
let request = Alamofire.request(.GET, urlString)
let imageRequest = ImageRequest(request: request)
imageRequest.request.response(
queue: queue,
responseSerializer: Request.imageResponseSerializer(),
completionHandler: { response in
guard let image = response.result.value else {
return
}
let decodeOperation = self.decodeImage(image) { image in
completion(image)
self.cacheImage(image, urlString: urlString)
}
imageRequest.decodeOperation = decodeOperation
}
)
return imageRequest
}

func decodeImage(image: UIImage, completion: (UIImage -> Void)) -> DecodeOperation {
let decodeOperation = DecodeOperation(image: image, decoder: self.decoder, completion: completion)
self.decoder.queue.addOperation(decodeOperation)
return decodeOperation
}

func cacheImage(image: Image, urlString: String) {
photoCache.addImage(image, withIdentifier: urlString)
}

func cachedImage(urlString: String) -> Image? {
return photoCache.imageWithIdentifier(urlString)
}

func purgeCache() {
// photoCache.removeAllImages()
print("memory used: \(photoCache.memoryUsage)")
}

}

最佳答案

问题

在 PhotosDataManager => 您正在使用 sharedManager 引用,它将对象引用保存在静态引用中并继续重用它,在所有 segues 导航中,因此您的 allPhotos 方法,继续在旧数组中添加数据。

 static let sharedManager = PhotosDataManager()

另一个问题

不要在 numberOfItemsInSection 中调用 allPhotos 方法,因为它会被多次调用,这可能会多次附加数据

解决方案

在你的方法中:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

//USE Instantiated reference
return photos.getPhotosCount()
}

相反,在你的类 PhotosDataManager
class PhotosDataManager {

func getPhotosCount(){

return photos.count
}
}

关于ios - Swift 2 reloadData 向 UICollectionView 添加了更多单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38005911/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com