Search code examples
iosswiftuitableviewuiscrollview

How to Add HeaderView from nib to UiTableView programmatically in Swift


Well i'm a naive IOS developer using swift language.

I have a table view which displays a list of features of a hotel.Now i want to add a header information to the tableView with hotel image, hotel name above the tableview so that the header information also scrolls along with tableview contents(product features list)

Here is the problem, TableView with list of features is working fine.

class HotelDetailViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {

    @IBOutlet weak var categoriesTableView: UITableView!

    var items: [(String, String,String)] = [
        ("Service", "   Courteous service, Good staff , Good staff","   Bad Facility"),
        ("Vibe",  "   Courteous service, Good staff","   Bad Facility"),
        ("Hotel",  "   Courteous service, Good staff","   Bad Facility"),
        ("Room Facility",  "   Courteous service, Good staff","   Bad Facility"),
        ("Amenities",  "   Courteous service, Good staff","   Bad Facility"),
        ("Food", "   Courteous service, Good staff","   Bad Facility")
    ]


    override func viewDidLoad() {
        super.viewDidLoad()
        let nib = UINib(nibName: "HotelSnippetTableViewCell", bundle: nil)
        categoriesTableView.separatorStyle = UITableViewCellSeparatorStyle.None
        categoriesTableView.registerNib(nib, forCellReuseIdentifier: "CustomCell")
        categoriesTableView.rowHeight = UITableViewAutomaticDimension
        categoriesTableView.estimatedRowHeight = 100    
    }



    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let customTableViewCell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! HotelSnippetTableViewCell

        let info  = items[indexPath.row]

        customTableViewCell.setCategory(info.0)

        customTableViewCell.setPositive(info.1)
        customTableViewCell.setNegative(info.2)


        return customTableViewCell

    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        print("You selected cell #\(indexPath.row)!")

    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }


}

For header information like hotelImage , hotel name and other labels i have created a nib with all the views set and a corresponding class with all the references mapped to it.

Now how to add this UiView to my tableview as a header programatically (because i get data after rest call).

I have searched but found tutorials on how to set string section headers.

Couple of things i tried out:

  1. I found that there is a protocol function for TableView

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
           //Code}
    

But how to load my nib here and set to this tableview and also i want ti trigger this programatically only after getting the data from service

  1. Create a nib with parent as TableViewCell, Load it using dequeueReusableCellWithIdentifier(), set info and set to tableview

        let headerCell =  categoriesTableView.dequeueReusableCellWithIdentifier("HotelDetailHeaderTableViewCell") as! HotelDetailHeaderTableViewCell  headerCell.setImageUrl("");
    
        headerCell.setHotelZmi(CGFloat(87))
    
    
        headerCell.setNameAndPersona("Fort Aguada Goa", persona: "OverAll", reviewsCount: "780")
    
        headerCell.frame = CGRectMake(0, 0, self.categoriesTableView.bounds.width, 600)
    
        categoriesTableView.tableHeaderView = headerCell
    

But even this is throwing some exception and i can't see where the exception is(How to see exception log in Xcode?).

Is the process i'm doing is correct? If not anyone please suggest me efficient approach

Because in Android i used to create a NestedScrollView with linear layout inside it embedded with any number of recyclerViews(removing scroll for recyclerviews) and Relativelayout

Please Help me.


Solution

  • You can use this code to init your nib file

    let view = (Bundle.main.loadNibNamed("MenuHeader", owner: self, options: nil)![0] as? UIView)
    
    tableView.tableHeaderView = view
    

    Then your MenuHeader will be a normal .xib file with your cell inside it, just remember to adjust the constraints appropriately to fit on all the screens that you want.