TableViewCell 中的 CollectionView 滚动在 swift3 中不流畅
CollectionView in TableViewCell scroll isn't smooth in swift3
在我的项目中 CollectionView
在 TableViewCell
中没有显示,我添加了
cell.collectionView.reloadData()
在我的代码中。我添加后,CollectionView
显示在TableViewCell
,但是
ScrollView
不顺利。如何解决这个问题呢。如果有人有任何经验或想法帮助我。谢谢。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "homecell") as! HomeCategoryRowCell
let mainThemeList = mainHomeThemeTable[(indexPath as NSIndexPath).row]
DispatchQueue.main.async {
cell.categoryTitle.text = mainThemeList.main_name
cell.collectionView.reloadData()
}
return cell
}
我项目中的 CollectionView,
extension HomeCategoryRowCell : UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
debugPrint("assetsTable count \(assetsTable.count)")
return assetsTable.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! HomeVideoCell
let list = assetsTable[(indexPath as NSIndexPath).row]
let url2 = NSURL(string:list.poster_image_url)
let data2 = NSData(contentsOf:url2! as URL)
// debugPrint(list.poster_image_url)
DispatchQueue.main.async(){
cell.movieTitle.text = list.name
cell.imageView.image = UIImage(data: data2! as Data)
}
return cell
}
}
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
添加以上代码后,我的项目变得更加顺利。我会尽力而为,然后返回最佳解决方案。谢谢
这是因为您直接从 url 获取数据,然后在主线程中从数据获取图像。您应该使用图像下载库从 url 下载图像
这是从 url 异步下载图像的好第三方。
https://github.com/rs/SDWebImage
试试这个,我 100% 确定它会解决您的问题。
谢谢
下载图像 Url collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
委托中的数据 - ASYNCHRONOUSLY
创建 Class
首先缓存关于key Image的图片数据URL
为什么要缓存数据?
因为 - 滚动时我们不需要每次都下载图像,所以缓存已经下载的图像数据和 return 缓存数据
我创建了一个 class 名称:AsyncImageLoader
然后我创建了一个函数,它是一个完成处理程序,它 return 在完成下载图像
后发送数据
class AsyncImageLoader {
static let cache = NSCache<NSString, NSData>()
class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) {
DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {
if let data = self.cache.object(forKey: url.absoluteString as NSString) {
DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
return
}
guard let data = NSData(contentsOf: url) else {
DispatchQueue.main.async { completionHandler(nil) }
return
}
self.cache.setObject(data, forKey: url.absoluteString as NSString)
DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
}
}
}
如何使用AsyncImageLoaderClass?
见下文我在collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
中是如何使用的
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let yourCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCollectionCell", for: indexPath) as! CustomCollectionCell
yourCell.url = URL(string: "\(item_ImageUrl)")
return yourCell
}
CustomCollectionCell
class CustomCollectionCell: UICollectionViewCell {
@IBOutlet weak var cellImageDisplayView: UIImageView!
var url: URL? {
didSet {
if let url = url {
cellImageDisplayView.image = nil
AsyncImageLoader.image(for: url, completionHandler: { (image) in
DispatchQueue.main.async {
if let img = image {
self.cellImageDisplayView.image = img
}else{
let dummyImage = UIImage(named: "img_u")
self.cellImageDisplayView.image = dummyImage
}
}
})
}else{
let dummyImage = UIImage(named: "img_u")
self.cellImageDisplayView.image = dummyImage
}
}
}
}
在我的项目中 CollectionView
在 TableViewCell
中没有显示,我添加了
cell.collectionView.reloadData()
在我的代码中。我添加后,CollectionView
显示在TableViewCell
,但是
ScrollView
不顺利。如何解决这个问题呢。如果有人有任何经验或想法帮助我。谢谢。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "homecell") as! HomeCategoryRowCell
let mainThemeList = mainHomeThemeTable[(indexPath as NSIndexPath).row]
DispatchQueue.main.async {
cell.categoryTitle.text = mainThemeList.main_name
cell.collectionView.reloadData()
}
return cell
}
我项目中的 CollectionView,
extension HomeCategoryRowCell : UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
debugPrint("assetsTable count \(assetsTable.count)")
return assetsTable.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! HomeVideoCell
let list = assetsTable[(indexPath as NSIndexPath).row]
let url2 = NSURL(string:list.poster_image_url)
let data2 = NSData(contentsOf:url2! as URL)
// debugPrint(list.poster_image_url)
DispatchQueue.main.async(){
cell.movieTitle.text = list.name
cell.imageView.image = UIImage(data: data2! as Data)
}
return cell
}
}
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
添加以上代码后,我的项目变得更加顺利。我会尽力而为,然后返回最佳解决方案。谢谢
这是因为您直接从 url 获取数据,然后在主线程中从数据获取图像。您应该使用图像下载库从 url 下载图像 这是从 url 异步下载图像的好第三方。
https://github.com/rs/SDWebImage
试试这个,我 100% 确定它会解决您的问题。
谢谢
下载图像 Url collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
委托中的数据 - ASYNCHRONOUSLY
创建 Class
首先缓存关于key Image的图片数据URL
为什么要缓存数据?
因为 - 滚动时我们不需要每次都下载图像,所以缓存已经下载的图像数据和 return 缓存数据
我创建了一个 class 名称:AsyncImageLoader
然后我创建了一个函数,它是一个完成处理程序,它 return 在完成下载图像
class AsyncImageLoader {
static let cache = NSCache<NSString, NSData>()
class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) {
DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {
if let data = self.cache.object(forKey: url.absoluteString as NSString) {
DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
return
}
guard let data = NSData(contentsOf: url) else {
DispatchQueue.main.async { completionHandler(nil) }
return
}
self.cache.setObject(data, forKey: url.absoluteString as NSString)
DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
}
}
}
如何使用AsyncImageLoaderClass?
见下文我在collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let yourCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCollectionCell", for: indexPath) as! CustomCollectionCell
yourCell.url = URL(string: "\(item_ImageUrl)")
return yourCell
}
CustomCollectionCell
class CustomCollectionCell: UICollectionViewCell {
@IBOutlet weak var cellImageDisplayView: UIImageView!
var url: URL? {
didSet {
if let url = url {
cellImageDisplayView.image = nil
AsyncImageLoader.image(for: url, completionHandler: { (image) in
DispatchQueue.main.async {
if let img = image {
self.cellImageDisplayView.image = img
}else{
let dummyImage = UIImage(named: "img_u")
self.cellImageDisplayView.image = dummyImage
}
}
})
}else{
let dummyImage = UIImage(named: "img_u")
self.cellImageDisplayView.image = dummyImage
}
}
}
}