Search code examples
iosswifttableviewuitabbarcontrollerxcode11

Not able to add UISearchBar in HeaderView(tableview's header view)?


Not able to see the searchBar in tableView section header everthing is done programmatically no storyboards used


import UIKit

class ConversationsViewController: UITableViewController {
    
    
    
    let searchBar:UISearchBar = {
        let bar = UISearchBar()
        bar.placeholder = "search conversations"
        bar.translatesAutoresizingMaskIntoConstraints = false
        return bar
    }()
    let headerView:UIView = {
        let hView = UIView()
//        hView.backgroundColor = .red
        hView.translatesAutoresizingMaskIntoConstraints = false
        return hView
        
    }()
    //    we want custom cell and header view
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

    }
//    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
//        return "section \(section)"
//    }
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        headerView.addSubview(searchBar)
        searchBar.centerXAnchor.constraint(equalTo: headerView.centerXAnchor).isActive = true
        searchBar.centerYAnchor.constraint(equalTo: headerView.centerYAnchor).isActive = true
        searchBar.heightAnchor.constraint(equalToConstant: 100).isActive = true
        searchBar.widthAnchor.constraint(equalToConstant: 40).isActive = true
        return headerView
    }
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 70
    }
}

here is the output photo here

I tried diff ways but I found this method to add headerView in tableView and now I can't figure out how to add that search bar in headerView , I tried above but it doesn't work , please help thank you


Solution

  • Couple things...

    A view for a section header should NOT have .translatesAutoresizingMaskIntoConstraints set to false. Leave it at the default of true.

    Don't give the UISearchBar a height constraint -- let it use its intrinsic height.

    We DO need to give the search bar a width constraint. If you want it to fit the width of the table, use:

    searchBar.widthAnchor.constraint(equalTo: headerView.widthAnchor, constant: 0.0).isActive = true
    

    If you want it to be only partial width, either give that line a negative value for the constant, or use a multiplier:

    // this will make the search bar 90% of the width of the table
    searchBar.widthAnchor.constraint(equalTo: headerView.widthAnchor, multiplier: 0.9).isActive = true
    

    Here is your class with those modifications:

    class ConversationsViewController: UITableViewController {
        
        let searchBar:UISearchBar = {
            let bar = UISearchBar()
            bar.placeholder = "search conversations"
            bar.translatesAutoresizingMaskIntoConstraints = false
            return bar
        }()
    
        let headerView:UIView = {
            let hView = UIView()
    
            // give it a background color so we can easily see
            //  if it is laying out correctly
            hView.backgroundColor = .red
    
            // section header view should leave this at the default TRUE
            //hView.translatesAutoresizingMaskIntoConstraints = false
    
            return hView
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            // add the searchBar
            headerView.addSubview(searchBar)
            
            // center it horizontally and vertically
            searchBar.centerXAnchor.constraint(equalTo: headerView.centerXAnchor).isActive = true
            searchBar.centerYAnchor.constraint(equalTo: headerView.centerYAnchor).isActive = true
            
            // don't set height constraint - use UISearchBar intrinsic height
            //searchBar.heightAnchor.constraint(equalToConstant: 100).isActive = true
            
            // constrain width equal to headerView width
            //  we can adjust the constant if we don't want it to span the entire width of the table
            //  by using a negative value for the constant, or using a mulitplier to get a percent of the width
            searchBar.widthAnchor.constraint(equalTo: headerView.widthAnchor, constant: 0.0).isActive = true
            
            return headerView
        }
        
        override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 70
        }
        
    }