为什么活动指标显示两次

时间:2015-03-22 22:59:23

标签: uitableview swift uiactivityindicatorview

我正在实现一个活动指示器,以便在获取/加载图像时显示。但是,活动指示器有时会在同一帧中显示两次。

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

活动指标代码(在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()
           }
      }
 }

enter image description here

更新

这是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()
        }

1 个答案:

答案 0 :(得分:1)

这是多次显示,因为您多次添加它。事实上,每当调用foodPhotoObjects.isEmpty的else案例时。

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

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

从表格视图中取消单元格。出列的工作原理如下:

  1. 它根据标识符维护一个队列。
  2. 如果队列中没有单元格,则会创建一个新单元格。
  3. 如果已经是一个单元格,它会将该单元格返回给您。哪个将被重复使用。
  4. 所以你正在做的是,你每次都要向小区添加MaterialActivityIndicatorView,无论是否先前添加过。

    <强>解决方案:

    1. 从xib向您的单元格添加自定义视图,并将其类设置为 MaterialActivityIndicatorView。并在此处获取参考 隐藏/显示和动画。
    2. 检查cell.mainRestaurantImageView的子视图,看看是否 那已经是MaterialActivityIndicatorView,得到它的参考 并做动画和东西。如果没有MaterialActivityIndicatorView的子视图,请创建一个并将其作为子视图添加到图像视图中。您将使用tag属性。
    3. 第二种方法可以这样做:

      //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.