Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 581
Manikanta Avatar asked Jul 19 '16 06:07

Manikanta


3 Answers

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.

like image 107
Ramon Vasconcelos Avatar answered Nov 16 '22 09:11

Ramon Vasconcelos


Update for swift 4

let view = (Bundle.main.loadNibNamed("TableViewHeader", owner: self, options: nil)![0] as? UIView) 
self.tableview.tableHeaderView = view
like image 31
Morteza Hosseini Zadeh Avatar answered Nov 16 '22 08:11

Morteza Hosseini Zadeh


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.

like image 1
Edward Avatar answered Nov 16 '22 07:11

Edward