UITableView space between row and sections - ios

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
}

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

How to make fixed height cell on uitableview?

So I want to make timeline content like instagram, I'm using custom cell on my uitableview. My problem is I already set the cell height to 345 on the storyboard but I get cell table like below:
and here is my custom cell on storyboard:
How can I fix it, so I can get the result like on my storyboard?
The reason that you are having this issue is you have probably set your Custom tableview cell's row height to 345 but that is not set as custom while your UITableview's row height is less than 345. So, what you need to do is go to storyboard and select the Table(UITableview) and set its row height to the maximum possible row height.
Let's assume that you are going to have two different kind of row heights. One with 345 and another with 325. As 325<345, you set your tableview's row height to 345.
Now, select the custom tableview cell and make its row height as custom and set that to either 345 or 325. In your case, it will be 345.
It should be good now.
However, more appropriate way when you have different cell size would be to use the delegate method for row height specification.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row==0){
return 345;
}
else if(indexPath.row==1){
return 325;
}
else{
return 300; //a default size if the cell index path is anything other than the 1st or second row.
}
}
Use this delegate method:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 345
}
In your UITableViewController subclass, set self.tableView.rowHeight = 345. Might be a bug with storyboard heights not being translated.
You can set Table View Cell height here.

How to make UITableViewCell display fullscreen (allow paging)?

I have a custom UITableView - Scroll, Paging Enable. Because each of my cell has one background image, I want each time I scroll up or down it will display each image as full screen. I try to make my UITableViewCell to be full screen (stretch its height as big as the tableview).
However, I've got a problem: when I scroll(paging), the cell doesn't display as full screen. It contains a small part of the next cell. Then the part of next cell increase bigger and bigger each time I scroll(paging) down.
I didn't see any Auto Layout Option for UITableViewCell, cannot add constraint to the prototype cell. Would you please suggest me the way to do it? Thank you very much.
i just add this two lines of code and it works for me
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return tableView.frame.size.height;
}
// ***** The following SWIFT function expands the cell image view to full screen (frame.size.height), adding to M.Salah's reply above.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableView.frame.size.height;
}

UITableView duplicate section header after updating row heights

In my iOS app, I have a UITextView inside a tableview cell.
The UITextView and hence the cell height expands when the frame required for the text entered by user exceeds the current height of the cell.
In order to achieve the above, I am calling [tableView beginUpdates] followed by [tableView endUpdates] to reload the height for the cells.
The above is resulting duplicate section headers overlapping the expanded cell.
Is there a way to fix this without calling [tableView reloadData]?
Appended below is some relevant code:
When there is a text change, I verify if the text will fit in current text view, if not the cell is expanded to the new height:
- (void)textViewDidChange:(UITextView *)textView {
CGFloat oldTextViewHeight = [(NSNumber *)[self.cachedTextViewHeightsDictionary objectForKey:indexPath] floatValue];
CGFloat newTextViewHeight = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)].height + CELL_HEIGHT_PADDING;
if (newTextViewHeight > oldTextViewHeight ||
(newTextViewHeight != oldTextViewHeight && oldTextViewHeight != TEXTVIEW_CELL_TEXTVIEW_HEIGHT)) {
[self reloadRowHeights];
}
}
- (void)reloadRowHeights {
// This will cause an animated update of the height of the UITableViewCell
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
It's also important to note that I am using a custom section header, which makes my problem similar to one mentioned here:
UITableView Custom Section Header, duplicate issue
I cannot however use the solution to above problem because I cannot reloadData for the tableView in middle of user entering text.
Try implementing
tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int)
delegate method if you didn't
Little late to the party, but I couldn't find a working solution on SO, and then I figured one out, so I thought I'd share.
I use UITableViewAutomaticDimension both for cell heights and for section header heights. My header view class is just a UIView subclass with some subviews as needed. Inside my tableView(:viewForHeaderInSection:) class, I just initialized a new header view as needed, and I was experiencing this duplicate headers issue. Not even reloadData helped.
What seems to have fixed it for me was to implement basic "cell re-use" for the headers. Something like this:
Store the header views in a dictionary somewhere in your view controller.
class ViewController: UIViewController {
var sectionHeaders: [Int: UIView] = [:]
// etc...
}
Then, upon request, return your existing section header view if available, or else create and store a new one.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let sectionHeader = self.sectionHeaders[section] {
return sectionHeader
} else {
let sectionHeader = YourSectionHeader()
// Setup as needed...
self.sectionHeaders[section] = sectionHeader
return sectionHeader
}
}

UITableView heightForHeaderInSection not working

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.

Resources