How to add loading Indicator in Footer of CollectionView in iOS

Form Interface builder,

In Attribute inspector with your Collection View selected check the Section Footer in Accessories. So, It will add footerview in your collection view and you can easily drag and drop activity indicator to this footerView.

Hope this can help you. :)


The easiest way it that add an UIView at the bottom of your ViewController add an ActivityIndicator to that view and set view's property hidden to checked, create an IBOutlet of that view, while loading data from server set outlet's property hidden=NO after data is loaded again hide the view. The same thing I've done in few of my apps using UICollectionViews or UITableView

EDIT

An another way is to add loading indicator in the footer of either CollectionView or tableview then make a network call in the below method

For CollectionView:

- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;

And For TableView:

- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section;

Swift 4.2

For CollectionView:

func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath)

For TableView:

func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int)

The simplest solution would be adding the activity indicator to a view and add that view to UICollectionReusableView.

In collection view :

private let footerView = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.white)


  override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.register(CollectionViewFooterView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "Footer")
        (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.footerReferenceSize = CGSize(width: collectionView.bounds.width, height: 50)
        
    }

   override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        if kind == UICollectionView.elementKindSectionFooter {
            let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Footer", for: indexPath)
            footer.addSubview(footerView)
            footerView.frame = CGRect(x: 0, y: 0, width: collectionView.bounds.width, height: 50)
            return footer
        }
        return UICollectionReusableView()
    }

customized class: add your customizations here if you need any

public class CollectionViewFooterView: UICollectionReusableView {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

just use: footerView.startAnimating() & footerView.stopAnimating() for start or stop the animation

***** Hope you like it .******


I found one very easy solution with help of CCBottomRefreshControl You need to just treat it like simple UIRefreshController

let bottomRefreshController = UIRefreshControl()
bottomRefreshController.triggerVerticalOffset = 50
bottomRefreshController.addTarget(self, action: #selector(ViewController.refreshBottom), forControlEvents: .ValueChanged)

collectionView.bottomRefreshControl = bottomRefreshController

func refreshBottom() {
     //api call for loading more data
     loadMoreData() 
}

and where you think you should stop loader simply

collectionView.bottomRefreshControl.endRefreshing()