I don't know why viewForHeaderInSection is not called in swift3. I've added heightForHeaderInSection in UITableView but not called unfortunately. Please help me to check how to fixed it.
func numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch (section) {
case 0:
return homeStrs.count
case 1:
return accountStrs.count
case 2:
return otherStrs.count
default:
return otherStrs.count
}
}
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = menuTable.dequeueReusableCell(withIdentifier: "MenuCell", for: indexPath) as! MenuCell
cell.layoutMargins = UIEdgeInsets.zero;
cell.lbNoti.isHidden = true
switch ((indexPath as NSIndexPath).section) {
case 0:
cell.lbMenuTitle?.text = homeStrs[(indexPath as NSIndexPath).row]
cell.imgIcon.image = UIImage (named: homeImgStrs[(indexPath as NSIndexPath).row])
case 1:
cell.lbMenuTitle?.text = accountStrs[(indexPath as NSIndexPath).row]
cell.imgIcon.image = UIImage (named: accountImgStrs[(indexPath as NSIndexPath).row])
case 2:
cell.lbMenuTitle?.text = otherStrs[(indexPath as NSIndexPath).row]
cell.imgIcon.image = UIImage (named: otherImgStrs[(indexPath as NSIndexPath).row])
default:
cell.lbMenuTitle?.text = "Other"
}
return cell
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
switch (section) {
case 1:
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.menuTable.frame.size.width, height: 30))
let menuHeaderLabel = UILabel(frame: CGRect(x: 20, y: 0, width: self.menuTable.frame.size.width, height: 28))
menuHeaderLabel.text = "Account Settings"
headerView.addSubview(menuHeaderLabel)
return headerView
case 2:
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.menuTable.frame.size.width, height: 30))
let menuHeaderLabel = UILabel(frame: CGRect(x: 20, y: 0, width: self.menuTable.frame.size.width, height: 28))
menuHeaderLabel.text = "Others"
headerView.addSubview(menuHeaderLabel)
return headerView
default:
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.menuTable.frame.size.width, height: 0))
return headerView
}
}
If someone else is having the same issue... Adding this line in viewDidLoad called the delegate methods therefore made the header appear:
self.tableView.estimatedSectionHeaderHeight = 80
You sure you've added UITableViewDelegate, UITableViewDataSource in your ViewController Class
In my case, adding self.tableView.sectionHeaderHeight = 80.0 to viewDidLoad did the magic.
Same issue occured with me that's because tableview find difficulties in calculating height for header but as I was using automatic height calculation from xCode 9, I cannot give any explicit height value as mentioned above. After some experimentation I got solution, we have to override this method as,
-(CGFloat)tableView:(UITableView *)tableView
estimatedHeightForHeaderInSection:(NSInteger)section
{
return 44.0f;
}
Although I have checked both options
Automatic Height Calculation
Automatic Estimated Height Calculation
from storyboard as apple says, but still I got this weird error.
Please Note: This Error was shown only on IOS-10 version not on IOS-11 version. Maybe it's a bug from xCode. Thanks
Related
Hi have an application where I use google autocomplete search but I had to write my networking code for it. The issue now is how do I show the Powered by Google text at the base of the tableView? I have check online for resources but havent got any option. Thanks in advance
You can add image in footer view :
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
{
if(section == tableView.numberOfSections - 1)
{
let footerView = UIView.init(frame: CGRect(x:0, y:0, width:tableView.frame.size.width, height:100))
footerView.backgroundColor = UIColor.clear
let imageView: UIImageView = UIImageView.init(frame: CGRect.init(x: 40, y: 0, width: footerView.frame.size.width - 80, height: 100))
imageView.image = #imageLiteral(resourceName: "google_logo")// google logo image
imageView.contentMode = UIViewContentMode.scaleAspectFit
footerView.addSubview(imageView)
return footerView
}
else
{
return nil
}
}
Please note you have to set footerView height as well :
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
{
if(section == tableView.numberOfSections - 1)
{
return 100
}
else
{
return 0.001
}
}
I have a table view that is subclassed and extended, then being set up in the View controller. The problem that I'm having is the delegate method ViewForHeaderInSection isn't being called, while the normal data source methods are being called.
(this is the TableView setup method, is called in ViewDidLoad. The table view is connected to the View Controller with IBOutlet)
func setup() {
self.dataSource = self as UITableViewDataSource
self.delegate = self
let nib = UINib(nibName: "MyTableViewCell", bundle: nil)
self.register(nib, forCellReuseIdentifier: "MyCell")
}
These are the extensions
extension MyTableView: UITableViewDataSource,UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
//print(Genres.total.rawValue)
return Genres.total.rawValue
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let tableSection = Genres(rawValue: section), let articleData = articleDictionary[tableSection] {
// print(articleData.count)
return articleData.count
}
print(0)
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell") as! MyTableViewCell
if let tableSection = Genres(rawValue: indexPath.section), let article = articleDictionary[tableSection]?[indexPath.row]{
cell.cellTitle.text = article.articleTitle
cell.cellImageView.image = article.articleImage
cell.cellEmojiReaction.text = article.articleEmojis
}
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 40.0))
view.backgroundColor = .brown
let label = UILabel(frame: CGRect(x: 16, y: 0, width: tableView.bounds.width, height: 40))
label.textColor = .blue
let tableSection = Genres(rawValue: section)
switch tableSection {
case .breakingNews?:
label.text = "Breaking News"
case .scienceAndTech?:
label.text = "Science and Tech"
case .entertainment?:
label.text = "Entertainment"
case .sports?:
label.text = "Sports"
default:
label.text = "Invalid"
}
print("Function Run")
view.addSubview(label)
print(label.text ?? "Nothing Here")
return view
}
}
Here is the View controller Code:
class ViewController: UIViewController {
#IBOutlet weak var myTableView: MyTableView!
override func viewDidLoad() {
super.viewDidLoad()
myTableView.setup()
}
}
Is there any specific reason why the delegate method isn't being called? Thank you in advance for your time.
For this you have to also implement one more method heightForHeaderInSection along with viewForHeaderInSection method.
If you are using viewForHeaderInSection delegate method then it is compulsory to use heightForHeaderInSection method other wise section header mehtod is not called
Prior to iOS 5.0, table views would automatically resize the heights
of headers to 0 for sections where
tableView(_:viewForHeaderInSection:) returned a nil view. In iOS 5.0
and later, you must return the actual height for each section header
in this method.
Official Link for more description https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614855-tableview
Add in viewDidLoad:
tableView.estimatedSectionHeaderHeight = 80
i get a response from API like this:
[{
"name":"apple"
"type": "Fruit"
"taste": sweet
}
{
"name":"lemon"
"type": "Fruit"
"taste": "not tasty"
}]
and now i want to set the title of the section as name of UITable view.
for this i have called this in my view controller as:
var modelclass = [FruitsModelclass]()
override func viewDidLoad()
{
self.loaddata()
}
func loaddata()
{
//here i have called the API and sucessfully get the response in data and assign as
self.modelclass = data
self.tableView.reloadData()
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath!) as FruitCell
let model = self.Modeldata[indexpath.row]
cell.textlabel.text = model.name
return cell
}
this is how i set the name to cell.How can i set this to my headerSection..??there are alot of json objects in my Api its not fixed one. Here i have presented only two in can anyone help me out..??
If you just want to add title...
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "SOME TEXT" //return your text here, may be
}
if you want control over header view then something like this
public func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat{
return 50 //height you want of section
}
public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?{
let vw = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 50))
//view for header, you can also use view from nib, but thats another matter
vw.backgroundColor = UIColor.white
let label = UILabel(frame: CGRect(x: 10, y: 0, width: tableView.frame.size.width-10, height: 50))
//add label or buttons or what ever u want to view....
label.text = “SOME TEXT“
vw.addSubview(label)
return vw
}
And as a side note numberOfSections is imp to show headers
It works perfectly on phones with a width of 320 like iPhone 4 and 5. When I test on the simulator for the 6 and up however, the uitableview section headers are no longer visible for some reason. Here is the relevant code:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 3
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRectMake(0, 0, self.tableView.frame.size.width, 30))
headerView.backgroundColor = UIColor(red:0.20, green:0.47, blue:0.45, alpha:1.00)
let sectionLabel = UILabel(frame: CGRectMake(0, 0, self.tableView.frame.size.width, 30))
switch section {
case 0:
sectionLabel.text = "Monday to Friday"
case 1:
sectionLabel.text = "Saturday"
case 2:
sectionLabel.text = "Sunday"
default:
sectionLabel.text = ""
}
sectionLabel.font = UIFont(name:"HelveticaNeue-Bold", size: 16.0)
sectionLabel.textColor = UIColor.whiteColor()
sectionLabel.textAlignment = NSTextAlignment.Center;
headerView.addSubview(sectionLabel)
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> Float {
return 30.0
}
BEFORE I tap on first tableview cell...
WHILE I tap on first tableview cell...
This is it working on iPhone 5...
In a previous project using ObjectiveC, I had a multiple section tableView showing section headers with different background colours and with header text that dynamically updated itself dependent upon the number of items within the section. It worked perfectly.
I have tried to replicate this code in a new project in which we are using Swift and it doesn't work. The header text displays correctly, but there is no background colour and most importantly, the section header overlays the top cell in each section rather than sitting above it. This is the relevant code:
// MARK: TableView delegates
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if let sections = fetchedResultsController!.sections {
return sections.count
}
return 0
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let sections = fetchedResultsController!.sections {
let currentSection = sections[section]
return currentSection.numberOfObjects
}
return 0
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRectMake(0, 0, tableView.bounds.size.width, 30))
let textHeader = UILabel(frame: CGRectMake(11, 0, 320, 20))
switch (section) {
case 0:
headerView.backgroundColor = UIColor.greenColor()
case 1:
headerView.backgroundColor = UIColor.blueColor()
case 2:
headerView.backgroundColor = UIColor.redColor()
case 3:
headerView.backgroundColor = UIColor.purpleColor()
default:
break
}
let hText: String = "\(fetchedResultsController!.sections![section].name)"
let hItems: String = "\((fetchedResultsController!.sections![section].numberOfObjects) - 1)"
let headerText: String = "\(hText) - \(hItems)items"
textHeader.text = headerText
textHeader.textColor = UIColor.whiteColor()
textHeader.backgroundColor = UIColor.clearColor()
headerView.addSubview(textHeader)
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat? {
return 20.0
}
The header overlays because its height is 30, and you return only 20.0 in heightForHeaderInSection func. the background color doesn't show up because you miss a break for each "case" in the switch statements.
Switch cases should end with break, then only it will return the backgroundcolor
Check below code
switch (section) {
case 0:
headerView.backgroundColor = UIColor.greenColor()
break
case 1:
headerView.backgroundColor = UIColor.blueColor()
break
case 2:
headerView.backgroundColor = UIColor.redColor()
break
case 3:
headerView.backgroundColor = UIColor.purpleColor()
break
default:
break
}