fphelp fphelp -3 years ago 130
Swift Question

Activity Indicator While Tableview Loads

In my Xcode project I load items into an

Array
and then present it on a
UITableView
. While these items load the
UITableView
is empty and is not aesthetically pleasing so I want to put an activity indicator in the
UITableView
while its loading the data. I have copied my code at the bottom. How do I implement this? (I heard something called a completion handler could possibly do the trick but I am not sure how to use it)

func loadAnimals() {
let animalQuery = PFQuery(className: "Animals")
animalQuery.whereKey("userID", equalTo: PFUser.current()?.objectId! ?? String()) //getting which user
animalQuery.limit = 10
animalQuery.findObjectsInBackground { (objects, error) in
if error == nil {
self.colorArray.removeAll(keepingCapacity: false)
self.animalNameArray.removeAll(keepingCapacity: false)
self.animalTypeArray.removeAll(keepingCapacity: false)

for object in objects! {
self.colorArray.append(object.value(forKey: "colorType") as! String) // add data to arrays
self.animalNameArray.append(object.value(forKey: "animalName") as! String) // add data to arrays
self.animalTypeArray.append(object.value(forKey: "animalType") as! String) // add data to arrays
}
self.tableView.reloadData()

} else {
print(error?.localizedDescription ?? String())
}
}
}


//places colors in rows

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! AnimalCell //connects to color cell

//Adds the animal information in the cells
cell.colorType.text = colorArray[indexPath.row]
cell.animalName.text = animalNameArray[indexPath.row]
cell.animalType.text = animalTypeArray[indexPath.row]

return cell
}

Answer Source

It seems you have an asynchronous function for loading the table view data. You just need to put activityIndicator.stopAnimating() inside there.

Add a UIActivityIndicatorView either programatically or through Storyboard to your table view controller. If you choose to do it in code, this is how you do it, including adding constraints to keep it in the middle of your view controller:

view.addSubview(activityIndicator)
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
activityIndicator.hidesWhenStopped = true
activityIndicator.color = UIColor.black
let horizontalConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)
view.addConstraint(horizontalConstraint)
let verticalConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)
view.addConstraint(verticalConstraint)

Before calling the above code inside viewDidLoad(), declare let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) somewhere in your class.

You just have to start animating it as soon as loadAnimals starts execution and stop it before calling tableView.reloadData(). Name it `activityIndicator, then do the following:

func loadAnimals() {
    activityIndicator.startAnimating()
    let animalQuery = PFQuery(className: "Animals")
    animalQuery.whereKey("userID", equalTo: PFUser.current()?.objectId! ?? String()) //getting which user
    animalQuery.limit = 10
    animalQuery.findObjectsInBackground { (objects, error) in
        if error == nil {
            self.colorArray.removeAll(keepingCapacity: false)
            self.animalNameArray.removeAll(keepingCapacity: false)                
            self.animalTypeArray.removeAll(keepingCapacity: false)

            for object in objects! {
                self.colorArray.append(object.value(forKey: "colorType") as! String) // add data to arrays
                self.animalNameArray.append(object.value(forKey: "animalName") as! String) // add data to arrays                    
                self.animalTypeArray.append(object.value(forKey: "animalType") as! String) // add data to arrays
            }
            activityIndicator.stopAnimating()
            self.tableView.reloadData()

        } else {
            print(error?.localizedDescription ?? String())
        }
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download