UITableView heightForHeaderInSection not working - ios

I have a simple UITableView (sample project here) but the section headers do not respect the height I'm setting in the heightForHeaderInSection
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 40;
}
The table view looks like this. The 1 section header has a correct height but not the other ones.
When I inspect the view with the Reveal app, it seems that there is a kind of footer after the last cell in the section.
What am I doing wrong?

What seems to work is this
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.0001f; // 0.0f does not work
}
or even better, in loadView
self.tableView.sectionFooterHeight = 0.0f;

Swift:
Swift version of approved answer:
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNonzeroMagnitude
}

Guessing into the blue and from your inside with the Reveal App try setting the footer to height 0.
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
According to the docs:
Special Considerations
Prior to iOS 5.0, table views would
automatically resize the heights of footers to 0 for sections where
tableView:viewForFooterInSection: returned a nil view. In iOS 5.0 and
later, you must return the actual height for each section footer in
this method.

Related

Dynamically change the section header text on a static cell

I have a UITableViewController, with its table view having static cells, defined in a storyboard.
My table view has two sections. The first with two cells, and the second section has three cells. The second section also has text in its header.
What I would like to do is that when the user taps the first or second cells in the first section, to update the header text of the second section. Do so dynamically and with dynamic content (say the date and time is displayed there as of the moment they tap cells).
I have tried numerous things, but the viewForHeaderSection is only called once.
I registered the header section cell with
tableView.registerClass(TableSectionHeader.self, forHeaderFooterViewReuseIdentifier: "secondSectionCell")
Where TableSectionHeader is simply:
class TableSectionHeader: UITableViewHeaderFooterView { }
I am then able to dynamically set the section header, like so:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 1 {
if let cell = tableView.dequeueReusableHeaderFooterViewWithIdentifier("secondSectionCell") {
cell.textLabel?.text = "hello world"
return cell
}
}
return nil
}
I also have implemented the following override, since some people suggest that when implementing viewForHeaderInSection, it is also required:
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40.0
}
Even still. viewForHeaderInSection is only called once.
Am I able to somehow refresh the section header text dynamically as described above?
You can actually achieve this using traditional table view way easily.
Even though it is static UITableView, in your dataSource view controller, you can still implement - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
So how do you update the title on the fly? Create a property for this view controller, say NSString *titleForSecondSection. Whenever user tap the cells in the first section, you just need to update this property in the callback - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
The last step is to call [self.tableView reload] after you modified the titleForSecondSection property. Or if you don't want to reload the whole table view, just call - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
To be clear, in your - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section, for sections that don't need to change title, just return a static string. For sections that need to change title, return the dynamic property you created.
viewForHeaderInSection would only be called when the tableview is reloaded. So assuming you don't want to reload the whole tableview, you might need to change the content of label directly.
pseudo codes like:
var label_first_section_header //as global variable
then in viewForHeaderInSection just point it to the label
if section == 1 {
if let cell = tableView.dequeueReusableHeaderFooterViewWithIdentifier("secondSectionCell") {
cell.textLabel?.text = "hello world"
label_first_section_header = cell.textLabel
return cell
}
}
then you can change the text dynamically whenever you want, for example in didSelectRowAtIndexPath

Hide First Section Header of a TableView Grouped in a UITableViewController - Swift 3 - Xcode8

This is my very first post here.
I need to mention I'm not a coder, I'm a UX designer and I'm trying to get fluent with Xcode Storyboard+ to build better prototypes for my fellow Engeneers.
The issue
I'm trying to give a "native" look to my profile view.
Right now my profile view is a UITableViewController.
I realized that the "native" look comes with the settings "grouped" applied to the TableView.
Here is how it looks compare to my previous version, not using "grouped"
As you can see, the grouped version pushed my TableView down because of the header. I haven't entered any text in the Header settings. Yet the space is taken by a fixed margin.
I want to get rid of that space.
I've found this code on Stack, that sounded like should be solving my issue.
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
let headerHeight: CGFloat
switch section {
case 0:
// hide the header
headerHeight = CGFloat.leastNonzeroMagnitude
default:
headerHeight = 21
}
return headerHeight
}
I've added this in my ProfileTableViewController.swift inside the super.viewDidLoad().
But the space remains and I am now out of options.
Maybe the problem comes from the header/footer settings and not even the section title... not even sure anymore.
The latest two options offered by #Pragnesh are working for me.
I'm not sure shifting the tableview up is the best practice ever, but it does the trick for now.
I'm sure there is still a way to just hide the section header.
I've been using this
self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0)
Try this:
In storyboard/xib:
1. Click TableView.
2. Click on Size Inspector on Right side.
3. You will see SectionHeight: Header and Footer.
4. Make both these values 1.
5. It will remove the extra spaces.
Set 1 as the first section header's height. Then I use the contentInset to hide that height underneath the navigation bar.Given below -
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == 0)
return 1.0f;
return 32.0f;
}
- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return nil;
} else {
// return some string here ...
}
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.tableView.contentInset = UIEdgeInsetsMake(-1.0f, 0.0f, 0.0f, 0.0);
}
You can try this code in viewDidLoad():
1). In viewDidLoad():
self.automaticallyAdjustsScrollViewInsets = false
2). Either you can write this in viewDidLoad():
self.tableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0)
3). Or you can write this:
self.tableView.contentInset = UIEdgeInsetsMake(-20, 0, -20, 0);
The other answers work, but I'd rather not mess around with hardcoded insets.
An improvement to #niku solution could be using CGFloat.leastNonzeroMagnitude
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return CGFloat.leastNonzeroMagnitude
}
// return the height for the other sections
}

UITableView space between row and sections

I want to make a UITableView as close to the iOS settings view as possible:
How do i create the space between different sections? What's the best way?
You just select grouped style in the Interface Builder and it will separate the table per section, similar as is in the screenshot.
Here is an attachment:
Change Style of UITableView to "Grouped"
try these..
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30; //according to your need..
}
i hope it helps..
First of all the iOS Settings doesn't use the ViewForSection otherwise the Section view would be placed in the top tableView.
You can return an empty containerView cell for that specific indexPath and stop didSelect in it, but remember to include the empty cells to the array you are using for other cells.
Just add the footer height in the table as required:
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 44
}

How to reduce space between section header?

I would like to eliminate the space in these two places programatically?
I have tried this without much luck:
- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
return 35.50;
}
- (CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section {
return CGFLOAT_MIN;
}
UPDATE:
I have seen this solution and it doesn't help me.
After applying the suggested solution of
self.yourTableView.sectionHeaderHeight = 0
self.yourTableView.sectionFooterHeight = 0
I get this, but thats not correct. The whole section title is gone.
It looks like your cell have margin
Open Debug>Debug view hierarchy and see where is your margin
Why you return 35.5 in the heightForHeaderInSection? It is your header height?
Try this and remove heightForHeaderInSection and heightForHeaderInSection functions from your UITableViewDelegate:
self.yourTableView.sectionHeaderHeight = 0
self.yourTableView.sectionFooterHeight = 0
Or this
-
(CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
return 0;
}
- (CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
I give you clear reference from below link
Click Here
Credit goes to Tomen

Dynamic table cell height

Using the storyboard, I've created a custom cell for my table view, I've also created a custom class for it with all my properties.
Now, what would be the best way in making the cells height dynamic, where is the best way to do this?
Should I do this in the custom class for the cell? Or in my table view controller?
I imagine it would make more sense to do this in the custom class, but then how should I do this?
Once a specific label is filled in, it should change the height of the cell
You cannot change the height of the cell from your custom drawing class.
You can do this in the viewController that has the UITableView only.
Either by specifying a hardcoded row height for all cells, or by using the
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
and specifying a height for the cells here.
If you want to have different heights for the cells, you should check the indexpath.row property and return the desired height value.
In case you want to change the height of an already drawn in screen cell, you will have to reload that cell to reflect the change using this:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Use the following code
-(CGFloat)heightForText:(NSString *)str width:(int)width font:(UIFont *)font lineBreakMode:(NSLineBreakMode) lineBreakMode
{
CGSize textSize;
textSize = [str boundingRectWithSize:CGSizeMake(width, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName : font} context:nil].size;
return textSize.height;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == self.yourTable)
{
NSMutableDictionary *dict = [self.yourArray objectAtIndex:indexPath.row] ;
return [self heightForText:[dict valueForKey:#"reviewDescription"] width:300 font:[UIFont fontWithName:kAppRegularFont size:15.0] lineBreakMode:0]+75;
}
return 70;
}
Set your view controller to be the delegate for the table view and then implement the following UITableViewDelegate method in the view controller:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Add these line into your "viewDidLoad" method
self.tableView.estimatedRowHeight = your height here
self.tableView.rowHeight = UITableViewAutomaticDimension;
Don't set default hight into delegate
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
}

Resources