UICollectionView reloadSection不会从视图层次结构中删除旧视图

时间:2017-01-02 12:24:59

标签: ios uicollectionview

重新加载部分时,

UICollectionView不会从视图层次结构中删除可重用的视图。这会给UIAutomation带来问题。

我创建了一个使用UICollectionView的简单应用程序,并显示了页眉,页脚和单元格。在点击“Reload”时,collectionView会显示不同数量的单元格。请参考下图。

enter image description here

启动应用程序时,它会显示2个单元格。点击“Reload”第一次显示8 cells并点击“Reload”第二次显示18 cells。点击“重新加载”第三次显示2个单元格。现在,此时如果我们使用Xcode View debugger调试视图,则在禁用“仅显示显示的视图”时,它会在视图层次结构中显示多个单元格。请参阅下图:

"Show only displayed Views" option enabled "Show only displayed Views" option disabled

这在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上传了此示例应用。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

因为每次重新加载一组不同的元素时:

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
}