UICollectionView reloadSection 不会从视图层次结构中删除旧视图
Posted
技术标签:
【中文标题】UICollectionView reloadSection 不会从视图层次结构中删除旧视图【英文标题】:UICollectionView reloadSection does not remove old views from view hierarchy 【发布时间】:2017-01-02 12:24:58 【问题描述】:UICollectionView
在重新加载部分时不会从视图层次结构中删除可重用视图。这会给UIAutomation
带来问题。
我创建了一个简单的应用程序,它使用UICollectionView
并显示页眉、页脚和单元格。点击“Reload
”时,collectionView
会显示不同数量的单元格。请参考下图。
启动应用时,它会显示 2 个单元格。第一次点击“Reload
”显示8 cells
,第二次点击“Reload
”显示18 cells
。第三次点击“重新加载”显示 2 个单元格。现在,如果我们使用Xcode View debugger
调试视图,当禁用“仅显示显示的视图”时,它会在视图层次结构中显示多个单元格。参考下图:
这在UIAutomation
中产生了获取元素的问题。我不确定我的实施有什么问题。
下面是我的控制器代码:
struct CellData
var title: String
var value: String
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
@IBOutlet var collectionView: UICollectionView!
private var data: [CellData]!
private var data1: [CellData]!
private var data2: [CellData]!
private var data3: [CellData]!
private var reloadIndex = 1
private var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.data1 = [
CellData(title: "Cell Title 1", value: "Value 1"),
CellData(title: "Cell Title 2", value: "Value 2")]
self.data = self.data1
self.data2 = [
CellData(title: "Cell Title 1", value: "Value 1"),
CellData(title: "Cell Title 2", value: "Value 2"),
CellData(title: "Cell Title 3", value: "Value 3"),
CellData(title: "Cell Title 4", value: "Value 4"),
CellData(title: "Cell Title 5", value: "Value 5"),
CellData(title: "Cell Title 6", value: "Value 6"),
CellData(title: "Cell Title 7", value: "Value 7"),
CellData(title: "Cell Title 8", value: "Value 8")]
self.data3 = [
CellData(title: "Cell Title 1", value: "Value 1"),
CellData(title: "Cell Title 2", value: "Value 2"),
CellData(title: "Cell Title 3", value: "Value 3"),
CellData(title: "Cell Title 4", value: "Value 4"),
CellData(title: "Cell Title 5", value: "Value 5"),
CellData(title: "Cell Title 6", value: "Value 6"),
CellData(title: "Cell Title 7", value: "Value 7"),
CellData(title: "Cell Title 8", value: "Value 8"),
CellData(title: "Cell Title 9", value: "Value 9"),
CellData(title: "Cell Title 10", value: "Value 10"),
CellData(title: "Cell Title 11", value: "Value 11"),
CellData(title: "Cell Title 12", value: "Value 12"),
CellData(title: "Cell Title 13", value: "Value 13"),
CellData(title: "Cell Title 14", value: "Value 14"),
CellData(title: "Cell Title 15", value: "Value 15"),
CellData(title: "Cell Title 16", value: "Value 16"),
CellData(title: "Cell Title 17", value: "Value 17"),
CellData(title: "Cell Title 18", value: "Value 18")]
self.collectionView.registerNib(UINib(nibName: "CollectionCell", bundle: nil), forCellWithReuseIdentifier: "CollectionCell")
self.collectionView.registerNib(UINib(nibName: "SectionHeader", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "SectionHeader")
self.collectionView.registerNib(UINib(nibName: "SectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "SectionFooter")
@IBAction func reload()
self.activityIndicator.center = self.view.center
self.view.addSubview(self.activityIndicator)
self.activityIndicator.startAnimating()
self.view.userInteractionEnabled = false
let waitTime = 2 * Double(NSEC_PER_SEC)
let dispatchTime = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), Int64(waitTime))
dispatch_after(dispatchTime, dispatch_get_main_queue())
self.reloadIndex += 1
if self.reloadIndex > 3
self.reloadIndex = 1
switch self.reloadIndex
case 2:
self.data = self.data2
break
case 3:
self.data = self.data3
break
default:
self.data = self.data1
self.collectionView.reloadSections(NSIndexSet(index: 0))
//self.collectionView.reloadData()
self.activityIndicator.stopAnimating()
self.activityIndicator.removeFromSuperview()
self.view.userInteractionEnabled = true
@IBAction func print()
printViewHierarchyInJSON(self.view)
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return self.data.count
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let compatibleCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCell", forIndexPath: indexPath)
(compatibleCell as? CollectionCell)?.setData(self.data[indexPath.item])
return compatibleCell
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
var supplementaryView = UICollectionReusableView()
switch kind
case UICollectionElementKindSectionHeader:
supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "SectionHeader", forIndexPath: indexPath)
case UICollectionElementKindSectionFooter:
supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionFooter, withReuseIdentifier: "SectionFooter", forIndexPath: indexPath)
default:
break
return supplementaryView
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
return CGSizeMake(collectionView.bounds.size.width, 50)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
return CGSizeMake(collectionView.bounds.size.width, 104)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize
return CGSizeMake(collectionView.bounds.size.width, 86)
我已在dropbox 上上传了此示例应用程序。
提前谢谢你。
【问题讨论】:
发布 UICollectionView "cellForItemAt" 代码 我为项目添加了 Dropbox 链接。这是:dropbox.com/s/gp20x3zz15f0vqx/CollectionViewDemo.zip?dl=0 【参考方案1】:因为每次重新加载不同的元素集:
self.reloadIndex += 1
if self.reloadIndex > 3
self.reloadIndex = 1
switch self.reloadIndex
case 2:
self.data = self.data2
case 3:
self.data = self.data3
default:
self.data = self.data1
【讨论】:
以上是关于UICollectionView reloadSection 不会从视图层次结构中删除旧视图的主要内容,如果未能解决你的问题,请参考以下文章
如何滚动另一个 UICollectionView 下方的 UICollectionView?
UICollectionView 单元内部已加载,但 UICollectionView 未显示
UICollectionView 断言失败 -[UICollectionView _updateWithItems:tentativelyForReordering:]
UITableviewCell 中的 UICollectionView。添加约束后,UICollectionView 不显示