In this blog, we will discuss Pagination in Swift.
Pagination in Swift is the ability to scroll to the bottom of the page and it automatically fetches more data.
Every app nowadays uses this feature to load more information. So let’s dive in.
Setting up for pagination in swift
Let’s create an Xcode project, add a table view in the Main storyboard.
Create TableViewCell and Xib. After that, register TableViewCell and assign delegate and dataSource.
Your TableViewCell.xib must contain a label to display the content.
Adding functionality
Firstly, we will need some data to populate the table view. We have defined a function “makeRequest”, which when called provides the data that will be used to display in the table view row.
Here is the code for the makeRequest function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
func makeRequest(isPagination: Bool, completion: @escaping (Result<[String], Error>) -> Void){ func makeRequest(isPagination: Bool, completion: @escaping (Result<[String], Error>) -> Void){ if isPagination{ isPaginationOn = true } DispatchQueue.global().asyncAfter(deadline: .now() + (isPagination ? 2 : 3), execute: { let data = ["Hello","You", "are","Welcome", "To", "Mobikul", "Hello","You", "are","Welcome", "To", "Mobikul","Hello","You", "are","Welcome", "To", "Mobikul","Hello","You", "are","Welcome", "To", "Mobikul", "Mobikul","Hello","You", "are","Welcome", "To", "Mobikul"] let nextData = ["Enjoy", "The", "Pagination", "Blog", "Enjoy", "The", "Pagination", "Blog", "Enjoy", "The", "Pagination", "Blog"] completion(.success(isPagination ? nextData : data)) if isPagination{ self.isPaginationOn = false } }) } |
We will now explain the working of the makeRequest function.
As you can see we have declared the constant “data” which contains the actual data that will be displayed before we start the pagination in table view.
We are using “isPagination” parameter to determine if the user has reached the bottom of the table view and requested the newData to load into the table view. For instance, if isPagination is true then “nextData” from the makeRequest function will be load in the table view.
Call the makeRequest function from the viewDidLoad like below
1 2 3 4 5 6 7 8 9 10 11 12 |
makeRequest(isPagination: false, completion: {[weak self] response in switch response{ case .success(let data): self?.data.append(contentsOf: data) DispatchQueue.main.async { self?.tableView.reloadData() } case .failure(let error): break } }) |
We have declared a variable “data” in which we are appending the data returned by the makeRequest function.
In case of success, we get the response and append it to the variable “data”. We are then reloading the table view in the main thread.
Till now we have shown how to load the data into the table view, now we will show when to load the data into the table view. Actually, it is when we reach the bottom of the table view.
Let us code for the actual pagination to start.
Implementing Pagination
Pagination starts when we reach the bottom of the table view. We all know that the table view is inherited from the UIScrollView, so we will be using the property of the UIScrollView to detect that we have reached scrolling to the bottom of the table view.
Firstly, we will have to conform our class with UIScrollViewDelegate, then we will be using its properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
func scrollViewDidScroll(_ scrollView: UIScrollView) { let pos = scrollView.contentOffset.y if pos > tableView.contentSize.height-50 - scrollView.frame.size.height{ guard !isPaginationOn else{ return } self.makeRequest(isPagination: true){ [weak self]response in switch response{ case .success(let data): self?.data.append(contentsOf: data) DispatchQueue.main.async { self?.tableView.reloadData() } case .failure(let error): break } } } } |
In this function, we are calculating the position of the scroll view scroller. If the value of the scroller exceeds the height of content size of the table view subtracting the height of the scroll view, then we are calling our makeRequest function to load additional data which is nextData.
On successful completion append the next data to variable data and reload the table view with new data.
This is how we achieved the pagination in swift.
Here is the full code for pagination.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import UIKit class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate{ private var data = [String]() var isPaginationOn = false @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() self.tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "TableViewCell") tableView.delegate = self tableView.dataSource = self makeRequest(isPagination: false, completion: {[weak self] response in switch response{ case .success(let data): self?.data.append(contentsOf: data) DispatchQueue.main.async { self?.tableView.reloadData() } case .failure(let error): break } }) } func makeRequest(isPagination: Bool, completion: @escaping (Result<[String], Error>) -> Void){ if isPagination{ isPaginationOn = true } DispatchQueue.global().asyncAfter(deadline: .now() + (isPagination ? 2 : 3), execute: { let data = ["Hello","You", "are","Welcome", "To", "Mobikul", "Hello","You", "are","Welcome", "To", "Mobikul","Hello","You", "are","Welcome", "To", "Mobikul","Hello","You", "are","Welcome", "To", "Mobikul", "Mobikul","Hello","You", "are","Welcome", "To", "Mobikul"] let nextData = ["Enjoy", "The", "Pagination", "Blog", "Enjoy", "The", "Pagination", "Blog", "Enjoy", "The", "Pagination", "Blog"] completion(.success(isPagination ? nextData : data)) if isPagination{ self.isPaginationOn = false } }) } func scrollViewDidScroll(_ scrollView: UIScrollView) { let pos = scrollView.contentOffset.y if pos > tableView.contentSize.height-50 - scrollView.frame.size.height{ guard !isPaginationOn else{ return } self.makeRequest(isPagination: true){ [weak self]response in switch response{ case .success(let data): self?.data.append(contentsOf: data) DispatchQueue.main.async { self?.tableView.reloadData() } case .failure(let error): break } } } } } extension ViewController{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)as! TableViewCell cell.celllabel.text = self.data[indexPath.row] return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 50 } } |
We hope you have enjoyed this blog.
For other blogs Please click here