UICollectionview with Search Bar – Swift iOS

First, we will create a collection view and populate the data in it. We are using a MySQL database for employees table and a PHP API to fetch all employees data from database. The output of API will be in JSON format so we will also learn how to encode JSON data in Swift. We will be displaying employee number and name in it.

Create collection view using storyboard

  1. First goto your storyboard, search for collection view and drag in in your main view.
  2. Your collection view will have a cell inside it. Search for label for employee number and drag it inside collection view cell.
Select collection view cell and set a custom class
and an identifer

Now select collection view, goto outlets, and attach data source & delegate of collection view to your view controller class.

Create a class for single cell layout named SingleCellView.swift:

import UIKit

class SingleCellView: UICollectionViewCell {
	// drag label outlet here
}

Select label from storyboard and drag it inside SingleCellView class:

Note: To drag label from storyboard into SingleCellView class, oepn storyboard, goto “Navigate” in menu and select “Open in assistant editor”. Then select the class file from left sidebar and it will appear in second window.

Populate data in UI collection view

We are receiving an array of objects from the API. Each object has employeeNumber, firstName, lastName, email and other fields as displayed above. We need to display them in each collection view cell:

EmployeeModel.swift

import Foundation

class EmployeeModel: Decodable {
    public var employeeNumber: String!
    
    public var firstName: String!
}
  1. Create an outlet for collection view same as we did for collection view cell labels.
  2. Open viewcontroller file and extend it with UICollectionViewDataSource and UICollectionViewDelegate
  3. Implement 2 functions, first for total number of items in collection view, and second for populating data in collection view cell.
  4. Create an array of EmployeeModel objects and initialize it as an empty array.
  5. We will be using NSURLConnection.sendAsynchronousRequest to fetch data from API.
  6. When the response is received, we validate the data using guard statement to make sure it is not null.
  7. Decode the JSON string into EmployeeModel array.

ViewController.swift

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UISearchBarDelegate {
    
    private var data: [EmployeeModel]! = []
    private var realData: [EmployeeModel]! = []
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let url: URL = URL(string: "http://192.168.43.64/test/api.php")!
        var request: URLRequest = URLRequest(url: url)
        request.httpMethod = "GET"
        
        // if using POST
//        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
//        let dataStr: String = "value=1&value=2"
//        let postData: Data = dataStr.data(using: .utf8)!
//        request.httpBody = postData
        
        NSURLConnection.sendAsynchronousRequest(request, queue: .main) { (response, data, error) in
            
            guard let data = data else {
                print(error)
                return
            }
            
            let responseString: String! = String(data: data, encoding: .utf8)
            
            do {
                
                let jsonDecoder: JSONDecoder = JSONDecoder()
                self.data = try jsonDecoder.decode([EmployeeModel].self, from: data)
                
                self.realData = self.data
                
                self.collectionView.reloadData()
            } catch {
                print(error.localizedDescription)
            }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.data.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let singleCell: SingleCellView = collectionView.dequeueReusableCell(withReuseIdentifier: "singleCell", for: indexPath) as! SingleCellView
        
        singleCell.employeeNumber.text = self.data[indexPath.item].employeeNumber
        
        singleCell.firstName.text = self.data[indexPath.item].firstName
        
        return singleCell
    }
}

Add search bar in collection view

First select your collection view and enable section header. This will create a re-usable view inside collection view.

  1. Search for “Search bar” and drag it inside re-usable view. Also give it a identifier like we did for collection view cell.
  2. Set the custom class for re-usableview (in our case SearchBarView.swift), we will create that class in a moment.

SearchBarView.swift

import UIKit

class SearchBarView: UICollectionReusableView {
	// drag search bar outlet here same as we did for collection view cell
}
  1. Add delegate of search bar to our view controller same as we did for collection view delegate.
  2. Extend view controller class with UISearchBarDelegate and implement 2 more functions in this class.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

	let searchView: UICollectionReusableView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "SearchBar", for: indexPath)
	return searchView
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
	self.data.removeAll()
        
	for item in self.realData {
		if (item.firstName.lowercased().contains(searchBar.text!.lowercased())) {
			self.data.append(item)
		}
	}
        
	if (searchBar.text!.isEmpty) {
		self.data = self.realData
	}
	self.collectionView.reloadData()
}

Now you will have a working collection view with search bar.

If you prefer to have video tutorial:

Leave a Reply

Please disable your adblocker or whitelist this site!