title: Limit the amount of cells shown in tableView, load more cells when scroll to last cell
body: <p>I'm trying to set up a table view that only shows a specific amount of cells.  Once that cell has been shown, the user can keep scrolling to show more cells.  As of right now I'm retrieving all the JSON data to be shown in viewDidLoad and storing them in an array.  Just for example purposes I'm trying to only show 2 cells at first, one the user scrolls to bottom of screen the next cell will appear.  This is my code so far:</p>
  
  <pre><code>class DrinkViewController: UIViewController {
  
    @IBOutlet weak var drinkTableView: UITableView!
  
  
    private let networkManager = NetworkManager.sharedManager
  
    fileprivate var totalDrinksArray: [CocktailModel] = []
    fileprivate var drinkImage: UIImage?
  
    fileprivate let DRINK_CELL_REUSE_IDENTIFIER = "drinkCell"
    fileprivate let DRINK_SEGUE = "detailDrinkSegue"
  
    var drinksPerPage = 2
    var loadingData = false
  
    override func viewDidLoad() {
      super.viewDidLoad()
  
      drinkTableView.delegate = self
      drinkTableView.dataSource = self
  
      networkManager.getJSONData(function: urlFunction.search, catagory: urlCatagory.cocktail, listCatagory: nil, drinkType: "margarita", isList: false, completion: { data in
  
        self.parseJSONData(data)
  
      })
    }
  
  }
  
  extension DrinkViewController {
  
    //MARK: JSON parser
    fileprivate func parseJSONData(_ jsonData: Data?){
      if let data = jsonData {
  
        do {
          let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : AnyObject]//Parses data into a dictionary
  
          // print(jsonDictionary!)
          if let drinkDictionary = jsonDictionary!["drinks"] as? [[String: Any]] {
            for drink in drinkDictionary {
              let drinkName = drink["strDrink"] as? String ?? ""
              let catagory = drink["strCategory"] as? String
              let drinkTypeIBA = drink["strIBA"] as? String
              let alcoholicType = drink["strAlcoholic"] as? String
              let glassType = drink["strGlass"] as? String
              let drinkInstructions = drink["strInstructions"] as? String
              let drinkThumbnailUrl = drink["strDrinkThumb"] as? String
  
              let cocktailDrink = CocktailModel(drinkName: drinkName, catagory: catagory, drinkTypeIBA: drinkTypeIBA, alcoholicType: alcoholicType, glassType: glassType, drinkInstructions: drinkInstructions, drinkThumbnailUrl: drinkThumbnailUrl)
  
              self.totalDrinksArray.append(cocktailDrink)
            }
          }
        } catch let error as NSError {
          print("Error: \(error.localizedDescription)")
  
        }
      }
  
      DispatchQueue.main.async {
        self.drinkTableView.reloadData()
      }
    }
  
  
    //MARK: Image Downloader
    func updateImage (imageUrl: String, onSucceed: @escaping () -&gt; Void, onFailure: @escaping (_ error:NSError)-&gt; Void){
      //named imageData because this is the data to be used to get image, can be named anything
      networkManager.downloadImage(imageUrl: imageUrl, onSucceed: { (imageData) in
        if let image = UIImage(data: imageData) {
         self.drinkImage = image
        }
        onSucceed()//must call completion handler
      }) { (error) in
        onFailure(error)
      }
    }
  }
  
  
  //MARK: Tableview Delegates
  extension DrinkViewController: UITableViewDelegate, UITableViewDataSource {
  
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
  
      //return numberOfRows
      return drinksPerPage
    }
  
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      let cell = drinkTableView.dequeueReusableCell(withIdentifier: DRINK_CELL_REUSE_IDENTIFIER) as! DrinkCell
  
  
      //get image from separate url
      if let image = totalDrinksArray[indexPath.row].drinkThumbnailUrl{//index out of range error here
        updateImage(imageUrl: image, onSucceed: {
          if let currentImage = self.drinkImage{
            DispatchQueue.main.async {
              cell.drinkImage.image = currentImage
            }
          }
        }, onFailure: { (error) in
          print(error)
        })
      }
      cell.drinkLabel.text = totalDrinksArray[indexPath.row].drinkName
      return cell
    }
  
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      if let image = totalDrinksArray[indexPath.row].drinkThumbnailUrl{
        updateImage(imageUrl: image, onSucceed: {
        }, onFailure: { (error) in
          print(error)
        })
      }
      performSegue(withIdentifier: DRINK_SEGUE, sender: indexPath.row)
    }
  
  
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
      let lastElement = drinksPerPage
        if indexPath.row == lastElement {
           self.drinkTableView.reloadData()
        }
    }
  }
  </code></pre>
  
  <p>I saw this post: <a href="https://stackoverflow.com/questions/47020315/tableview-loading-more-cell-when-scroll-to-bottom">tableview-loading-more-cell-when-scroll-to-bottom</a> and implemented the willDisplay function but am getting an "index out of range" error.</p>