Uneven section header size in static UITableView - ios

I've created a simple static UITableView which is embedded in a UINavigationController. I don't understand why the height of the first section header is greater than that of the height of the section header after the first section. I want the height of the section headers to be the same.
Note: I'd like to do everything in the Storyboard if possible.

I don't think you can do this just in Storyboard. The only way I have been able to get things looking the way I want is to implement something like;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section==0)
{
return 25;
}
else
if (section==1)
{
return 35;
} // etc etc
And then, in Storyboard, adjust the Table View Size, Section Height values.

Related

Remove space at the top of first row in table view

In my application i'm using custom cell in table view to display images in all rows. But in my .xib file there is a big empty space comes at the top of the custom cell. Can anyone tell me that how remove that space in iOS7 (iPad)? (like how to change the Y axis of the custom cell)
This is an IOS7 related issue with UITableViewStyleGrouped and size of footer views in section.
If you set the footerView to be size 0 it defaults to a larger value, The solution I found was to set the footer to a very small non zero number
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 0.0000001f;
}
Try to set into your property inspector like this..
This might help you:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *sectionHeader = [[UILabel alloc] initWithFrame:CGRectNull];
sectionHeader.hidden = YES;
return sectionHeader;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0;
}
Sometimes the empty space in the first row is the section header space. This functions eliminate it.

How to add footer view for UITableView in IB when working with storyboards?

Playing around with prototype cells and I need to add footer view at the bottom of table view, so a user could see this footer view when he would scroll to the bottom of the table view. So, created demo project with one screen, table view and two prototype cells. Looking for a way how to drag and drop some view below the table using Interface Builder. The problem is it looks like view is put outside table view content, so I see the footer but I can't scroll to it (only a small part of footer view is seen at the bottom of the table view).
I know this should work because already saw a working implementation but cannot figure out what magic setting or code line I need to add.
Here are the methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
return 2;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat rowHeight = 10;
switch (indexPath.row) {
case 0: {
rowHeight = 376;
break;
}
case 1: {
rowHeight = 105;
break;
}
}
return rowHeight;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row) {
case 0: {
Cell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:#"Cell1" forIndexPath:indexPath];
return cell1;
break;
}
case 1: {
Cell2 *cell2 = [tableView dequeueReusableCellWithIdentifier:#"Cell2" forIndexPath:indexPath];
return cell2;
break;
}
}
return nil;
}
Just making 2 row table with two different height cells. Cell1 and Cell2 classes are empty subclasses of UITableViewCell.
Here's how table view and cells look in interface builder:
Here's initial view after launch:
Here's what I see if I scroll to the bottom:
The footer is there, but outside table view (scroll content). As you can see, table view by default reserves some 44px space at the bottom for footer. But if I set footer height in tableView:heightForFooterInSection: then blank spaces appear.
Also, tried to drag and move this view up to view hierarchy in IB, so the view would become a header view. In that case, the view is shown at the top as header view, but then the second cell is shown only partially when scrolling to the bottom. It looks like table calculates how much space it needs to show prototype dynamic cells (have set "Dynamic Prototypes" for the table view). And if you add extra footer or header view to the interface builder then there's less space for the cells (if view is added as header) or the footer is not shown.
UPDATE. If I add this method then blank spaces appear:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 50;
}
Here's what I get in that case (blank spaces below cell2):
UPDATE2 Footer is shown correctly if I disable autolayout.
I think you have missed the following line
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return HEIGHT_OF_YOUR_FOOTER_VIEW;
}
Edit
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *footer=[[UIView alloc] initWithFrame:CGRectMake(0,0,320.0,50.0)];
footer.layer.backgroundColor = [UIColor orangeColor].CGColor;
return footer;
}
Updated
Check this documentation
At last found the solution. Have noticed footer is shown correctly when autolayout is disabled, so started to look at constraints. So, have added leading space to container, trailing space, bottom space and top space to container constraints to table view using Ctrl + Drag. However IB showed red warning about missing Y position constraint. So, after choosing "Add missing constraints" from IB suggestion panel, IB added another system constraint but the footer was still not show correctly. It appears IB was unable to add correct top space and bottom space to container system constraints, and even to fix that. So I'v got 5 system constraints as a result of that:
Adding system constraints using Ctrl + Drag from table view to containing view have worked in previous demos for me. However, this time IB was unable to add correct top space and bottom space to container, and so top space vertical constraint had a value of -568. Tried setting to 0 but it didn't worked. Tried ten times to delete all constraints and add them again. The same result.
So, I deleted all these vertical (bottom and space) constraints and then selected "Add missing constraints". And bingo! IB added correct vertical constraints and the footer view was shown correctly. Here's how correct constraints should look like. However, I still don't understand why IB was unable to add correct constraints when I was doing Ctrl + Drag from table view to container view.

Change the height of a static UITableViewCell only possible by overriding heightForRowAtIndexPath?

I've looked through lots of examples of how to hide a static UITableViewCell by overridding heightForRowAtIndexPath, and while I've now got it working it just seems so cumbersome that I'd like to see if I'm doing something wrong.
I have a UITableViewController with a table view that has about 8 rows. This screen in my app shows a single object, so for example one row is description, one is an image, one holds a map view, etc. All of the rows are static.
In some cases, some of the objects that are shown don't have a map, so I want to hide the row that holds the mapview. Since it's a static row, I was thinking that by having an outlet property for that row (e.g. #property (weak, nonatomic) IBOutlet UITableViewCell *mapViewRow;), then I could somehow set that row's height to 0 or hide that row in viewDidLoad or viewWillAppear. However, it seems like the only way to do this is to override the heightForRowAtIndexPath method, which is kind of annoying because then I need to hardcode the index of the map row in my code, e.g.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 6 && self.displayItem.shouldHideMap) {
return 0;
}
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
Of course, not a big deal, but just the whole way of sizing static rows in a tableview seems like it defeats the point of setting them up in the storyboard in the first place.
EDIT - rationale behind my answer
To change the height of a row you must reload either the whole table or a subset containing that row. B/c it's a bit odd to have a row in the table w/ zero height, I prefer modifying your data source such that the row doesn't exist in the table.
There are a number of ways to do that. You could build an array from your displayItem where each row in the array corresponds to a row in the table w/ appropriate data. You would rebuild this array and then call [tableView reloadData]. My original answer would also eliminate the unwanted row by treating each data element as a section with 0 or 1 rows.
ORIGINAL ANSWER
Is your tableview a plain or grouped style? If it's a plain style, you could treat each row as a section with either 0 or 1 rows in it. In your tableView dataSource and delegate methods you would use the section index to identify the data within self.displayItem that you care about for that section.
Your code would be something like:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 8; // max number of possible rows in table
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 1;
// set self.mapSectionIndex during initialization or hard code it
if (section == self.mapSectionIndex && self.displayItem.shouldHideMap) {
rows = 0;
}
return rows;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:indexPath
{
return 60.0f; // whatever you want the height to be
}
// also modify tableView:cellForRowAtIndexPath: and any other tableView delegate and dataSource methods appropriately
you can override heightForRowAtIndexPath and just write in it return UITableViewAutomaticDimension; this will make cell calculate the height automatically as UILabel height is >= . it worked for me.

footer text in tableview is not showing

I have a basic grouped table view where i have implemented the two methods for setting header and footer for each section. Now, the header text is showing and working just fine. But the text in the footer view is not showing. I have 3 sections and only want to add text to the first footer section. The code:
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if ( section == 0 ) {
return #"Lorem ipsum";
}
return nil;
}
Now the weird thing is that it seems that the table is actually making space for the text, it's just not showing. I think there might be some really simple explanation to this, but can't seem to find it:)
I guess you are having heightForFooterInSection method in your viewController. If you are returning any value here, it is the problem. If you are doing, change your code like
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (section == 0) {
return 30.0f;
}
return 0.0f;
}

How can I customize some of a UITableView's cell heights, but leave others as defaults?

To specify cell heights of a table view we use the delegate method,
- (CGFloat) tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section
However this method asks cell height of every row, what can I do if I want some of them to be defaults?
For cell height we may return UITableView#rowHeight for those default rows inside the delegate method, but I also want some (not all) of the section headers/cell to be customized.
But I am not able to get the defaults from the table view, especially for grouped style table view, anyone has a solution?
Thanks!
EDIT: I'm sorry for not making it very clear. In fact, cell height is not the only one that I want to partially customize, but also something else like section header (there may be more, like delete button style, etc.).
Is there solution without mimicking default behavior?
if you don't want default behavior in all cases, you'll still have to mimic default behavior in the non-specialized cases.
for headers, you will still have to implement
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
and therein, you will have to answer the default height for those headers you do not wish to change, and the specialized header height for those you do want to change.
similarly, in
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*);
you will still have to mimic default behavior for those cells you do not wish to change.
you could accomplish all of this with storyboard if you want: create specialized cells with unique identifiers for each, and then return the cell heights that go with them. if you take this route, then you may be able to get away with just using dequeueReuaableCellWithIdentifier and using the height value for that identifier. just use a unique cell identifier with a height that's appropriate for each cell you're thinking of.
The default height of cell is 44 .. so you can return it when your condition is not satisfied ..
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (YOUR_SPECIFIC_CONDITION) {
return 180.0;
}
return 44.0;
}
May this will help you..
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0 && indexPath.section==0)
{
return 180.0;
}
else
{
return 44.0;
}
}

Resources