像Facebook这样的Swift TableView Footer ActivityIndi​​catorView。 当滚动更多的数据加载

我想做一个TableView页脚activityIndi​​catorView像Facebook一样,当从Web上滚动下载更多的数据时,也可以说是infiniteScrollingView。

我的无限滚动是好的,但有三个问题在那里

  1. footerView的背景空间不会隐藏完成​​从Web上加载数据后。

  2. activityIndi​​catorView正在上下移动,但我想把activityIndi​​catorView总是像Facebook一样。

  3. 如果数据有显示activityIndi​​catorView

NetworkRequestAPI请求

import Foundation class NetworkRequestAPI { static func getPropductListByCategory(productId : Int, pageNo : Int , completion: @escaping ([Product]? , Error?) -> ()){ let url = URL(string: Configuration.BASE_URL+"/product-by/type?product_type_id="+String(productId)+"&page="+String(pageNo)) var categoryObject = [Product]() URLSession.shared.dataTask(with:url!) { (urlContent, response, error) in if error != nil { } else { do { let json = try JSONSerialization.jsonObject(with: urlContent!) as! [String:Any] let products = json["products"] as? [String: Any] // productCount = (json["product_count"] as? Int)! let items = products?["data"] as? [[String:Any]] items?.forEach { item in let oProduct = Product() oProduct.product_id = item["product_id"] as? Int oProduct.product_name = item["product_name"] as? String oProduct.product_image = item["product_image"] as? String let ratingItem = item["rating_info"] as? [String: AnyObject] let rating = RatingInfo() rating.final_rating = ratingItem?["final_rating"] as? String oProduct.rating_info = rating categoryObject.append(oProduct) } completion(categoryObject, nil) } catch let error as NSError { print(error) completion(nil, error) } } }.resume() } } 

ListTableView类

 class ListTableView: UITableViewController { var isInitUILoad = true var arrProduct = [[Product]]() var pageNo = 1 override func viewDidLoad() { super.viewDidLoad() self.initUILoad() } func initUILoad(){ ActivityIndicator.customActivityIndicatory(self.view, startAnimate: true) NetworkRequestAPI.getPropductListByCategory(productId: product_id, pageNo: pageNo) { (products, error) in DispatchQueue.main.async(execute: { if products != nil { self.pageNo += 1 self.arrProduct.append(products!) print(self.arrProduct.count) }else{ print(error.debugDescription) } ActivityIndicator.customActivityIndicatory(self.view, startAnimate: false) self.tableView?.reloadData() self.isInitUILoad = false }) } } func loadMore(complition:@escaping (Bool) -> ()) { NetworkRequestAPI.getPropductListByCategory(productId: product_id, pageNo: pageNo) { (products, error) in DispatchQueue.main.async(execute: { if error != nil{ print(error.debugDescription) } if products != nil && products?.count ?? 0 > 0{ self.pageNo += 1 self.arrProduct.append(products!) self.tableView?.insertSections([self.arrProduct.count - 1], with: .fade) }else{ print("no product left") } complition(true) }) } } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: categoryCellid, for: indexPath) as! ListTableCell var categoryObject = arrProduct[indexPath.section] cell.product = categoryObject[indexPath.item] return cell } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 115.0 } override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { let footerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerCellid) as! HeadFooterCell if !isInitUILoad { footerView.activityIndicatorView.startAnimating() loadMore(complition: { (isDone) in footerView.activityIndicatorView.stopAnimating() }) } return footerView } override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return 50 } } 

** HeadFooterCell **

 class HeadFooterCell: UITableViewHeaderFooterView { override init(reuseIdentifier: String?) { super.init(reuseIdentifier: reuseIdentifier) setupViews() } var activityIndicatorView : UIActivityIndicatorView = { var activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray) activityIndicatorView.backgroundColor = UIColor.cyan return activityIndicatorView }() func setupViews() { addSubview(activityIndicatorView) addConstraintsWithFormat("H:|[v0]|", views: activityIndicatorView) addConstraintsWithFormat("V:|[v0(50)]|", views: activityIndicatorView) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }