活动指示器不禁用CollectionViewCell

时间:2016-04-23 08:22:59

标签: ios swift uicollectionview uicollectionviewcell uiactivityindicatorview

我有3个单元格的Collection视图。我正在显示图像,但是,从服务器获取图像数据需要几秒钟,我使用nsuserdefaults和缓存。

let imagesFromUserDefaults
var dataIsFetched = false

viewDidLoad() {
   let imagesFromUserDefaults = // Data from user defaults
}

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

   let cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("ACollectionViewCell", forIndexPath: indexPath) as! ACollectionViewCell

   let activityView = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
   activityView.hidesWhenStopped = true

   if dataIsFetched == false {
        activityView.center = CGPointMake( cell.contentView.frame.size.width / 2, cell.contentView.frame.size.height / 2) 

        cell.contentView.addSubview(activityView)
        activityView.startAnimating()

        cell.img = // set image - works
   } else {
        // Data is fetched from the Server
        activityView.stopAnimating()

        cell.img = // set image - works
   }

func fetchDataFromServer() {
     // onSuccessResponse: Store into Array

     dataIsFetched = true
     collectionView.reloadData()
}

但是,加载服务器数据后,即使图像发生变化,活动指示也不会消失。因此,如果单元格具有相同的indexPath.row(图像也证明了这一点),为什么活动指示符不会发生呢?

此外,将此行为置于CollectionViewCell类更合乎逻辑吗?什么是正确的处理方式

编辑:

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

        if initialLoad {
            count = self.defaults.count
        } else {
            count = self.fetched[0].count
        }

        print("number of cells \(count)")
        if count < 4 {
            return count
        }

        return 0

    }

2 个答案:

答案 0 :(得分:1)

您需要设置

let activityView = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
activityView.hidesWhenStopped = true

此外,您可以设置activityView.center = cell.center以获得更清晰的代码。

答案 1 :(得分:0)

你知道,收集视图单元是可重用的,集合视图中显示的3个单元可以共享同一个单元实例。因此,每次调用cellForItemAtIndexPath方法时,您可能会获得相同的单元格实例,并且您反复向单元格添加活动指示符但从不删除它。这不好。想象一下,如果用YES / NO获取图像,你将指示是什么,这很容易,如果获取图像,则在单元格中显示YES,否则为NO。因此,指标在这里做同样的事情,指标的YES是动画,NO不是动画,不要被欺骗,因为它在旋转,它不是用于跟踪整个提取过程。您需要做的就是在原型单元格中添加指标,并保持图像的状态,是否取出。并根据状态更新指标:

var isImageFetched = yourImagesStates[indexPath.row];
if isImageFetched == true {
    cell.indicator.stopAnimating()
    cell.img = image
} else {
    cell.indicator.startAnimating()
}

希望它会有所帮助。