UITableView separator lines disappear between cells on scroll - uitableview

Problem: The separator between cells in a table view appear only for those cells shown when the view loads, and only at load time. When the tableview is scrolled down, the cells scrolled into view show no separator between them, then when the tableview is scrolled back up, the initial cells show no separator.
Details: I've got a UITableView to which I'm adding standard UITableViewCells. These cells are created with initWithFrame, frame height = 90px. I'm adding a custom view created from a nib to this cell's view, height = 90px. The cell height is specified at 90px in tableView:heightForRowAtIndexPath:.
Has anyone experienced this behavior?

I had a feeling the solution to this would be simple...
I made the height of my cells 91px and the separator lines appear as they should on scroll.

I couldn't use Douglas's solution because my tables have a huge amount of cells and would become pretty much unusable on older phone. Reusing cells is key for performance.
BUT, I managed to workaround the problem using a transparent separator and adding my own in the contentView of the cell, as follows:
yourTable.separatorColor = [UIColor clearColor];
separatorView.frame = FactRectMake(0, rowHeight-1, appFrame.size.width, 0.2);

I had the same problem, but I used a different solution.
My separators were disappearing because I was clearing my cell using:
for (UIView *eachView in self.subviews) {
[eachView removeFromSuperview];
}
This removed the separator view as well!
Instead, I assigned a tag for each of my customs views (three labels) right before adding them to the sub view:
tempFirstNameLabel.tag = 100;
self.firstNameLabel = tempFirstNameLabel;
[self addSubview:self.firstNameLabel];
Then when I cleared the cell, I just removed those views:
for (int i = 100; i<103; i++) {
UIView *eachView = [self viewWithTag:i];
[eachView removeFromSuperview];
}
Hope this helps!
This also avoids the memory management issues that #Douglas Smith's solution posed.

You should set separator none and then single line again
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// it is a bug in iOS 7
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;

Related

UITableview displays limited cells

I have a UITableView that is setup correct and at some point I wanted
to display only a limited amount of cells. Now that I want to revert back
the functionality I am unable to do so.
The property that limits the visible cells (according to my git log):
// This will remove extra separators from tableview
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
After removing the above line, I still do not get the desired effect.
But something was introduced, and I am not sure what to search for.
I want the default behavior back with many empty cells.
Here is my methods for the sections and data, currently I only have
two cells visible.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [data count];
}
View Hierarchy Debugging data.
I am adding images of the View Debugger, "Wire Frame View" and "Content View" seperately.
From the images you will see two types of separator lines;
I mimicked a line by adding space at the bottom of the cell
so that I could have "thin lines".
Please check the tableview height. I think height of the table currently you are seeing is less so you are getting only 2 visible cells.
As one can see from the attached images, the wire frames show that the separators are in fact drawn but they are not visibly on the screen when you view the content.
Simply change the colors:
self.tableView.backgroundColor = [UIColor redColor];
self.tableView.separatorColor = [UIColor greenColor];

UITableView with drop shadow

I know how to add a shadow around UIViews and even to animate them when the views bounds change. However I've come across a view that is a little more tricky it seems. UITableView
Adding a shadow around this view is easy enough and even going by this example: Adding drop shadow to UITableView
It works well. However my problem is that I need the shadow to go around the last cell in the UITableView and not it's bounds. So, top, sides and bottom would be the last cell in the UITableView.
Thinking about how it'd work leaves me to believe there is a better solution. Maybe if I was able to adjust the UitableViews frame based on the number of cells? However the cells are dynamic and I don't know their heights until runtime.
Any suggestions would greatly be appreciated.
Thanks!
something like...
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1) {
// last row
cell.layer.shadowOpacity = 0.5;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRect:cell.bounds].CGPath;
cell.layer.masksToBounds = NO;
}
}
Only one option for your requirement :
1) Add shadow for top, left and right of UITableView.
2) Add shadow to bottom of last UITableViewCell. For this you might need to increase height of last cell of UITableView;

UITableView grouped hide section separator

I know this question has been asked before. But no person on the internet had a working and sufficient answer.
EDIT Obviously people don't read questions anymore, on SO. So I'm trying to clarify: I want to remove the SEPARATOR. The separator is neither the space above the section, nor the tableViewHeader or tableViewFooterView. It is only the thin line above (fully from left to right).
I have a grouped UITableView (I don't want to use a plain styled for many other reasons, take it as it is) which has multiple groups.
The first section should not have the separator line on top. Setting the separator style of the tableView is not an option, because I do need the other separators.
Setting the tableViews tableFooterView is something I often read, but it never worked.
I used the tableView with static content before and I was able to remove the separator in -[UITableViewController viewDidLoad] using this:
- (void)viewDidLoad {
[[[self headerTableCell] valueForKey:#"_topSeparatorView"] removeFromSuperView];
}
Since I now had to change the tableView to a dynamic one, the IBOutlet property won't work anymore (obviously).
So I tried everything, -[id tableView:willDisplayCell:atIndexPath:], -[UITableViewCell initWithStyle:reuseIdentifier:, prepareForReuse, awakeFromNib] and some others.
In any case, this separator is nil. So I need a method that gets called when the complete view hierarchy of the cell is setup.
what i get from your situation you have a grouped UITableView you want the first section without separator and you want to keep the separator in the other sections so
remove the separator from the whole tableview from the attributes inspector make Separator : None
create custom UITableviewCell in storyboard for other sections and add View at the end of it with height 1 and width the whole screen (like default separator)
it's maybe not the best idea but this will allow you to have the first section without separator
I faced a similar problem, wanted to remove the last line of the section in grouped table view, I am calling following method in view will appear and on every table reload. This is not the exact answer but problem can be solved by just changing y value of dummy view.
+(void)removeLastSectionSeparatorForTableView:(UITableView *)tableView
{
UIView *oldSeparatorView = [tableView viewWithTag:kTagDummySectionSeparator];
if (oldSeparatorView != nil)
{
[oldSeparatorView removeFromSuperview];
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(),
^{
UIView *view = [[UIView alloc] init];
view.tag = kTagDummySectionSeparator;
view.backgroundColor = [UIColor colorWithRed:239.0/255 green:239.0/255 blue:244.0/255 alpha:1.0];//Group table background color
view.frame = CGRectMake(0,
tableView.contentSize.height-40,
tableView.bounds.size.width,
2);
[tableView addSubview:view];
});
}
Maybe this problem is the same as mine before.
Finally, my way to solve this problem: set table view delegate's method (CGFloat)tableView:(UITableView *)tableView heightForHeaderAtSection:(NSInteger)section, then return CGFLOAT_MIN;
add this override function in your Custom Cell Class
override func layoutSubviews() {
super.layoutSubviews()
for subview in subviews where (subview != contentView && abs(subview.frame.width - frame.width) <= 0.1 && subview.frame.height < 2) {
subview.removeFromSuperview()
}
}

UITableViewCell hidden content overlaps on other cells

I have a table,with settings that cell height is 40px.
If my cells have a label, image or any other component starting at 41px it will still appear in the table overlaping the cells underneath.
How to resolve this? I do not want the rest of the cell to be shown, just the height that is
set in my table settings.
Thank you.
Please add up these methods and try,
-(float)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section
{
return 0.01;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 1)] autorelease];
view.backgroundColor = [UIColor clearColor];
return view;
}
Using this will be considered as end of data from data source. And rest cells will not be displayed.
[Will solve this issue - If my cells have a label, image or any other component starting at 41px it will still appear in the table overlaping the cells underneath]
You want to hide the content of cell that is below the 40px level? Add UIView to cell.contentView with white colour above the content of cell with 41px origin.y
A little late, but just in case anyone else is running into this issue. If using IB, ensure "Clip Subviews" is checked on your table view cell. And this:
self.contentView.clipsToBounds = YES;
should do the same thing.
You didn't solve this problem because the point is not the UITableViewCell. It's Aspect Fill Mode of UIImageView.
Select the UIImageView in the SB, check this on!

How to remove header and footer space from a UITableView?

I have a UITableView in the grouped style, and only one section. However there is some blank space above and below the table view that is shown when the user scrolls too far. How can I remove this blank space?
You can do this by altering the contentInset property that the table view inherits from UIScrollView.
self.tableView.contentInset = UIEdgeInsetsMake(-20, 0, -20, 0);
This will make the top and bottom touch the edge.
Add this code:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0;
}
Actually this question answered my question.
Reducing the space between sections of the UITableView.
UIView can be inserted at the top and bottom of the table(drag and drop). Set their properties as transparent and height of 1 px. This is to remove the extra padding in front of the cells.
you can also use this code for removing space between first cell of uitableview..
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.002f;// set this...
}
Uncheck Extend Edges Under Top bar.
This answer comes quite late, but I hope it helps someone.
The space is there because of the UITableView's tableHeaderView property. When the the tableHeaderView property is nil Apple defaults a view. So the way around this is to create an empty view with a height greater than 0. Setting this overrides the default view thereby removing the unwanted space.
This can be done in a Storyboard by dragging a view to the top of a tableView and then setting the height of the view to a value of 1 or greater.
Or it can be done programmatically with the following code:
Objective-C:
CGRect frame = CGRectZero;
frame.size.height = CGFLOAT_MIN;
[self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:frame]];
Swift:
var frame = CGRect.zero
frame.size.height = .leastNormalMagnitude
tableView.tableHeaderView = UIView(frame: frame)
Comments
As others have noted you can use this same solution for footers.
Sources and Acknowledgements
See the Documentation for more details on the tableHeaderView property.
Thanks to #liushuaikobe for verifying using the least positive normal number works.
My original answer: https://stackoverflow.com/a/22185534/2789144
In my case issue was with the constraints i was applying. I have to change them in order to show 2 rows in my case while bottom of table touching last row.
Use the bounces property of UIScrollView:
[yourTableView setBounces:NO];
This will remove what seems to be an extra padding at the top and bottom of your UITableView.
Actually, it will just disable the tableview's scrollview to scroll past the edge of the content.

Resources