为什么 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 视图中使单元格出队。出队工作如下:
- 它维护一个基于标识符的队列。
- 如果队列中没有单元格,它会创建一个新单元格。
- 如果已经有一个单元格,它 returns 那个单元格给你。哪些将被重新使用。
所以您所做的是,每次都向单元格中添加 MaterialActivityIndicatorView
,无论之前是否添加过。
解法:
- 从 xib 向您的单元格添加自定义视图,并将其 class 设置为
MaterialActivityIndicatorView
。并在此处获取参考
hide/show 和动画。
- 检查
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.
我正在实现 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 视图中使单元格出队。出队工作如下:
- 它维护一个基于标识符的队列。
- 如果队列中没有单元格,它会创建一个新单元格。
- 如果已经有一个单元格,它 returns 那个单元格给你。哪些将被重新使用。
所以您所做的是,每次都向单元格中添加 MaterialActivityIndicatorView
,无论之前是否添加过。
解法:
- 从 xib 向您的单元格添加自定义视图,并将其 class 设置为
MaterialActivityIndicatorView
。并在此处获取参考 hide/show 和动画。 - 检查
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.