为什么 Activity 指标显示两次

Why is Activity Indicator Showing Twice

我正在实现 activity 指示器,以便在图像为 fetched/loads 时显示。但是,activity 指示器有时会在同一帧中出现两次。

我检查了无数次代码,甚至尝试了其他方法,例如匹配行号的计数器。知道为什么会出现两次吗? (见下图)

Activity指标代码(在cellForRowAtIndexPath内):

 // start indicator when loading images
 var indicatorPhoto: MaterialActivityIndicatorView! = MaterialActivityIndicatorView(style: .Small)
 indicatorPhoto.center = cell.mainRestaurantImageView.center
 cell.mainRestaurantImageView.addSubview(indicatorPhoto)
 indicatorPhoto!.startAnimating()

 cell.mainRestaurantImageView.loadInBackground {
      (success: UIImage!, error: NSError!) -> Void in
      if ((success) != nil) {
           // stop indicator when loading images
           if indicatorPhoto?.isAnimating == true {
                 indicatorPhoto!.stopAnimating()
                 indicatorPhoto!.removeFromSuperview()
           }
      } else {
           println("Unsuccessful Fetch Image")
           if indicatorPhoto?.isAnimating == true {
                indicatorPhoto!.stopAnimating()
                indicatorPhoto!.removeFromSuperview()
           }
      }
 }

更新:

这是 cellForRowAtIndexPath 代码的其余部分

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("RestaurantCell", forIndexPath: indexPath) as FeedCell

        cell.nameLabel.text = restaurantNames[indexPath.row]
        cell.photoNameLabel.text = photoNames[indexPath.row]
        cell.cityLabel.text = " " + addressCity[indexPath.row]
        cell.distanceLabel?.text = arrayRoundedDistances[indexPath.row] + "mi"

        // check if there are images
        if foodPhotoObjects.isEmpty {  } else {
            var restaurantArrayData = self.foodPhotoObjects[indexPath.row] as PFObject
            cell.mainRestaurantImageView.image = UIImage(named: "") // set placeholder
            cell.mainRestaurantImageView.file = restaurantArrayData["SmPhotoUploaded"] as PFFile

            // start indicator when loading images
            var indicatorPhoto: MaterialActivityIndicatorView! = MaterialActivityIndicatorView(style: .Small)
            indicatorPhoto.center = cell.mainRestaurantImageView.center
            cell.mainRestaurantImageView.addSubview(indicatorPhoto)
            indicatorPhoto!.startAnimating()

            cell.mainRestaurantImageView.loadInBackground {
                (success: UIImage!, error: NSError!) -> Void in
                if ((success) != nil) {
                    // stop indicator when loading images
                    if indicatorPhoto?.isAnimating == true {
                        indicatorPhoto!.stopAnimating()
                        indicatorPhoto!.removeFromSuperview()
                    }
                } else {
                    println("Unsuccessful Fetch Image")
                    if indicatorPhoto?.isAnimating == true {
                        indicatorPhoto!.stopAnimating()
                        indicatorPhoto!.removeFromSuperview()
                    }
                }
            }

            cell.mainRestaurantImageView.contentMode = .ScaleAspectFill
            cell.mainRestaurantImageView.clipsToBounds = true

        }

        return cell
    }

更新 2

// create indicator when loading images
        var indicatorPhoto : MaterialActivityIndicatorView? = cell.mainRestaurantImageView.viewWithTag(123) as? MaterialActivityIndicatorView;
        if indicatorPhoto == nil{
            indicatorPhoto = MaterialActivityIndicatorView(style: .Small)
            indicatorPhoto!.center = cell.mainRestaurantImageView.center
            indicatorPhoto!.tag = 123
            cell.mainRestaurantImageView.addSubview(indicatorPhoto!)
            indicatorPhoto!.startAnimating()
        }

这显示了多次,因为您添加了多次。事实上每次调用 foodPhotoObjects.isEmpty 的 else 情况时。

这是因为,您方法的第一行:

let cell = tableView.dequeueReusableCellWithIdentifier("RestaurantCell", forIndexPath: indexPath) as FeedCell

从 table 视图中使单元格出队。出队工作如下:

  1. 它维护一个基于标识符的队列。
  2. 如果队列中没有单元格,它会创建一个新单元格。
  3. 如果已经有一个单元格,它 returns 那个单元格给你。哪些将被重新使用。

所以您所做的是,每次都向单元格中添加 MaterialActivityIndicatorView,无论之前是否添加过。

解法:

  1. 从 xib 向您的单元格添加自定义视图,并将其 class 设置为 MaterialActivityIndicatorView。并在此处获取参考 hide/show 和动画。
  2. 检查cell.mainRestaurantImageView的子视图是否 已经有一个 MaterialActivityIndicatorView,获取它的参考 做动画之类的。如果没有 MaterialActivityIndicatorView 的子视图,请创建一个并将其作为子视图添加到图像视图中。为此,您将使用标签 属性。

第二种方法可以这样做:

//first find the activity indication with tag 123, if its found, cast it to its proper class
var indicatorPhoto : MaterialActivityIndicatorView? = cell.mainRestaurantImageView.viewWithTag(123) as? MaterialActivityIndicatorView;
if indicatorPhoto == nil{
    //seems it wasn't found as subview initialize here and add to mainRestaurantImageView with tag 123
}
//do rest of the stuff.