How to Add HeaderView from nib to UiTableView programmatically in Swift

14,254

Solution 1

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.

Solution 2

Update for swift 4

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

Solution 3

I would recommend using the UITableViewDelegate methods of tableView(:viewForHeaderInSection:) and tableView(:heightForHeaderInSection:).

You can then do the following:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = Bundle.main.loadNibNamed("ExampleTableHeaderView", owner: self, options: nil)?.first as? UIView
    return headerView
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 10
}

Other answers involve force unwrapping (!) and placing in brackets which is not necessary.

Share:
14,254
Manikanta
Author by

Manikanta

Native Android & IOS Developer with knowledge on ReactNative (TypeScript)

Updated on June 08, 2022

Comments

  • Manikanta
    Manikanta almost 2 years

    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.

  • Manikanta
    Manikanta almost 8 years
    I have created a UiView NIB and mapped to a swift class , and mapped the views interfaces to this classes so that i can edit values of the labels in the nib. Using the above code i am getting UiView, How can i access views inside the UiView Nib (like imageview, labels inside UIView)?
  • Manikanta
    Manikanta almost 8 years
    have created a UiView NIB and mapped to a swift class , and mapped the views interfaces to this classes so that i can edit values of the labels in the nib. Using the above code i am getting UiView, How can i access views inside the UiView Nib (like imageview, labels inside UIView)?
  • xmhafiz
    xmhafiz almost 8 years
  • Manikanta
    Manikanta almost 8 years
    The link tells about creating a label programatically, But i want to access views from nib.
  • Ramon Vasconcelos
    Ramon Vasconcelos almost 8 years
    If you already have a class for your UIView you have to connect your nib file with this class and then you can use "view.label.text" and then change your values. Remember to keep a reference of this view or just create a new one when you have to change the header information.
  • xmhafiz
    xmhafiz almost 8 years
    no, the question on creating custom uiview. but for your case, you can refer my update answer where I set the label on uiview
  • Sakthimuthiah
    Sakthimuthiah about 7 years
    Thanks a lot, you saved my life
  • Jordan Soltman
    Jordan Soltman over 5 years
    This doesn't create a header for the table view, but instead headers for each section which is not what OP is looking for.