Separator on the last UITableViewCell not added? - ios

This is how my UITableView looks like:
I might cut the image to close to the last cell but there is no separator on the last cell.
When running this on my device that has IOS 7.1.1 It gets the same result until i scroll the view up and down a bit and then it automatically adds the separator. But trying that in the simulator which is running on IOS 8.2 as you can se nothing happens.
So what i want is simply so the separator is visible from the start.
Many thanks
EDIT1
After trying the answer below it did work however when there are a lot of cells and you scroll up then an extra separator shows up as you can see.
Check the third last cell. That extra separator just follows me when i go up and down.
EDIT2
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:#selector(setSeparatorInset:)])
{
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)])
{
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
-(void)viewDidLayoutSubviews
{
if ([self.tableView respondsToSelector:#selector(setSeparatorInset:)])
{
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:#selector(setLayoutMargins:)])
{
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
return 76.0f;
else
return 25.0f;
}

Use the two below UITableView delegate methods
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView* view = [UIView new];
[view setBackgroundColor:[UIColor grayColor]];
return view;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 1.0f;
}

Try to add footer view for table with 1 0r 2 pixel height.

This worked flawlessly for me
self.tableFooterView = [[UIView alloc] init]

Related

Remove Separator from Grouped UItableview

I'm using an UITableView Style Grouped Seperator NO
When the table view loads I See a small distance between the cells.
and when scrolled it goes away
Need to get rid of that line. what is that I'm missing.
Use this, it will help you.
Write this in your viewDidLoad
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
And write this method for UITableView
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:#selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:#selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
Thanks All,
Have solved this by setting Bottom Constraint of the view to -1, and unchecked Clip To Bounds for both UITableViewCell and its Content View.

iOS UITableView Bug - White line on every other tableview cell

I have a weird bug in a UITableView I've implemented that uses custom cells.
Every other cell has a white line at the bottom of it. This line is only present on iPhone 5 and iPhone 6. It does not show on iPhone 6+. Two screenshots are provided from the iPhone 6 simulator (where you see the line) and the iPhone 6+ simulator (where you don't see the line).
I've tried every solution on stackoverflow but none of them are working. Namely, I've added the following methods to my table view:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if ([self.tableView respondsToSelector:#selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:#selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
if ([tableView respondsToSelector:#selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:#selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
and the following method to my custom cell:
- (UIEdgeInsets)layoutMargins {
return UIEdgeInsetsZero;
}
Yet the line is still seen on every other cell. Any ideas on how to get rid of this line? Thank you!
Please check your cell height in storyboard.if it is custom cell than confirm your cell height.
I faced same issue and my mistake was cell height.
Also check in .m file whether cell height method returns different height or not.
Otherwise check all view by applying different colors.

UITableViewController - cells size separator and backgroundcolor

I'm trying to achieve airbnb look for my UITableViewController.
separators are not in the full width of the screen
each cell has a unique size and background color
I've managed to tackle #2 using static table and setting each cell size in IB but have the following problems:
setting a background color in IB didn't take (changed both background color as well as tint)
I wish to "delete" a cell programmatically when it has no content but the only function that returns cell height - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
is generic for all cells and is called prior to populating the cells with data, so at this method I can't decide if the cell should be deleted or not.
I think you should use the delegate method willDisplayCell: forRowAtIndexPath: of the table view. This delegate method is called just before the cell is ready to be displayed on the table view. In this delegate you will have the cell created, if you need some modifications you can do here, which will be reflected just before the cell is displayed.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setBackgroundColor:[UIColor redColor]];
// and all other cell customizations
}
You could set separatorInset and layoutMargins properties of table view before layout subviews and cell's separatorInset and layoutMargins properties before displaying cell.
For setting custom cell's height you may get needed cell by calling a table view data source method instead of call cellForRowAtIndexPath: method of table view.
Example:
// 1. Make full width separators:
- (void)viewWillLayoutSubviews {
if ([self.tableView respondsToSelector:#selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:#selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
#pragma mark - Table view data source
// 2.Customize cells background color and height
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = [NSString stringWithFormat:#"s%ld-r%ld", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
if (indexPath.row % 2) {
cell.backgroundColor = [UIColor redColor];
cell.contentView.backgroundColor = [UIColor whiteColor];
cell.textLabel.text = cellIdentifier;
} else {
cell.backgroundColor = [UIColor cyanColor];
cell.contentView.backgroundColor = [UIColor whiteColor];//background color of contentView overlaps cell's background color
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; //getting cell at indexPath
if ([self isCellEmpty:cell]) {
return 22;
}
return 44;
}
- (BOOL)isCellEmpty:(UITableViewCell *)cell {
return !cell.textLabel.text.length; //Place your code for checking cell's content
}

Reduced cell in grouped UITableview

I am adding one more section to the existing tableView and getting this:
my new cell is reduced by height. Appropriate methods:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return cells[indexPath.section][indexPath.row];
}
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if ([headers[section] isKindOfClass:[UIView class]])
return [headers[section] frame].size.height;
return 10.0f;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if ([headers[section] isKindOfClass:[UIView class]])
return headers[section];
return nil;
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = cells[indexPath.section][indexPath.row];
if (cell == clientXibCell) return 100.0f;
if (cell == agencyXibCell) return 145.0f;
return 46.0f;
}
I can't understand what I need to do to fix this. Any ideas where the source of issue can be?
Update
I am now sure that predefining custom cell visual interface making this trouble.
supervisorCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
bgView = [[UIImageView alloc] initWithFrame:supervisorCell.backgroundView.frame];
[bgView setImage:stretchableImageByHorizontal([UIImage imageNamed:#"cell_bgd_bottom"])];
[supervisorCell setBackgroundView:bgView];
bgView = [[UIImageView alloc] initWithFrame:supervisorCell.backgroundView.frame];
[bgView setImage:stretchableImageByHorizontal([UIImage imageNamed:#"cell_bgd_bottom_active"])];
[supervisorCell setSelectedBackgroundView:bgView];
When I am uncommenting everything except first statement of creating the cell, everything works fine except custom appearance of cell. What do I need to change in this simple code to fix this?
The height of your cells are controlled by the heightForRowAtIndexPath:. Taking a look on your code, it seems that this method is always returning 46.
Your two ifs are comparing pointers, i. e., instancies of your cells. It means that of all your cells, one will have the height 100, one 145 and all others 46.f.
I think what are you trying to accomplish is set this height for all cells of the same kind, so you should change your heightForRowAtIndexPath: method, like below:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ( [cell isKindOfClass:[YourCustomCell1 class]] ) return 100.0f;
if ( [cell isKindOfClass:[YourCustomCell2 class]] ) return 145.0f;
return 46.0f;
}
Ps1: Change YourCustomCell class for your own classes. If you don't have subclasses, try to set tags or something like that to differentiate them.
Ps2: always use tableview's method cellForRowAtIndexPath to get the reference of the cell by the indexPath.

UITableView didselectrowatindexpath not getting called

For some reason my UITableView Delegate method didSelectRowAtIndexPath is not getting called until after I select the row. Also, although I set the editing style of my UITableView to UITableViewCellEditingStyleDelete, when I swipe my finger across the tableview it doesn't show the delete button. I have set the delegate and datasource properties of my tableview in storyboard to my viewcontroller, but the delegate methods still aren't getting called properly. The cells still function and will navigate to my other detailview, but I'm just getting some very weird behavior. Here's the code I'm using for my tableview:
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_lists count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MasterListCell";
/* Set up list cell */
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
CGRect myImageRect = CGRectMake(0.0f, 0.0f, 15.0f, 15.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"cell-arrow.png"]];
cell.accessoryView = myImage; //cellArrowNotScaled;
cell.editingAccessoryType = UITableViewCellEditingStyleDelete;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
/* Define a new List */
List *list = [_lists objectAtIndex:indexPath.row];
// cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:#"Roboto-Medium" size:15];
cell.textLabel.text = list.name;
cell.textLabel.highlightedTextColor = [UIColor blackColor];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:
(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Are you sure?" message:#"This list will be permanently deleted." delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK",nil];
[alert show];
}
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
if (currentSelectedIndexPath != nil)
{
[[tableView cellForRowAtIndexPath:currentSelectedIndexPath] setBackgroundColor:[UIColor yellowColor]];
}
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"did select row");
[[tableView cellForRowAtIndexPath:indexPath] setBackgroundColor:[UIColor yellowColor]];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (cell.isSelected == YES)
{
[cell setBackgroundColor:[UIColor yellowColor]];
}
else
{
[cell setBackgroundColor:[UIColor whiteColor]];
}
}
Update answer
From your comment below, I see what you're getting at. You're trying to fake a custom selected background for grouped style (which can't be customized without providing custom images) by turing of selection highlighting and instead setting the unselected background color when the cell is tapped. You can do this in shouldHighlightRowAtIndexPath:
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor greenColor];
return YES;
}
This method gets called before didSelectRowAtIndexPath even when selection style is none. You'll need to elaborate on the above solution to set the color back when the cell is supposed to be unhighlighted.
Original answer
didSelectRowAtIndexPath is not getting called until after I select the row
That is by design, hence the past tense "did" in the name.
Also, although I set the editing style of my UITableView to UITableViewCellEditingStyleDelete, when I swipe my finger across the tableview it doesn't show the delete button.
You've got to implement the data source method tableView:commitEditingStyle:forRowAtIndexPath: to have the delete button appear. If you think about it it makes sense. You haven't provided a way for your data source to respond to the edit, so iOS concludes that it shouldn't edit.
I'm saying that when I press down on a cell with UITableViewSelectionStyleBlue it shows up blue. However, when I set it to none and attempt to change the background color in didSelectRowAtIndexPath it doesn't change until after I have lifted my finger up off the cell. I want the background color of the cell to change when I put my finger down without lifting it
What are you ultimately trying to accomplish? It sounds like you want to do a custom highlight color. The way to do that is to replace the cell's selectedBackgroundView with your own view and set that view's background color:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
cell.selectedBackgroundView.backgroundColor = [UIColor greenColor];
//...
}
If that's not what you're going for, please clarify and I'll update my answer.

Resources