UITableViewCell in ios7 now has gaps on left and right - uitableview

I have a UITableView where, in ios6, my custom cell stretched completely to the left and right sides of the screen. So my square image on the left of the cell was hard up against the phone screen.
However, now in ios7, there is a small gap appearing on the left hand side so the image is now away from the side and slightly overlaps my text within the cell.
This also seems to be happening in other apps I have that I am now viewing in ios7 - all have a gap on the left and perhaps the right as well.
My Custom cell is set to a size of 320 according to Interface Builder - ios 7 hasnt changed this has it?

iOS7 added a separatorInset property.
Try adding this to your UITableViewController:
if ([self.tableView respondsToSelector:#selector(separatorInset)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}

I'd prefer to make seperators myself. It feels simpler than struggling with tableview settings.Just set seperators to none, subclass your cells and do this in init.
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
UIView *seperator = [[UIView alloc] init];
[seperator setBackgroundColor:[UIColor blackColor]];
seperator.frame = CGRectMake(0, self.bounds.size.height-1, self.bounds.size.width, 1);
[seperator setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth];
[self.contentView addSubview:seperator];
}
return self;
}

This is working perfect for me:
-(void)viewDidLayoutSubviews
{
if ([self.Video_TableVIEW respondsToSelector:#selector(setSeparatorInset:)]) {
[self.Video_TableVIEW setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.Video_TableVIEW respondsToSelector:#selector(setLayoutMargins:)]) {
[self.Video_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];
}
}

Adding the image to the cell.contentView fixes the problem:
[cell.contentView addSubview:imgView];
This way you don't even have to mind the separatorInset property.

For those using Xamarin/MonoTouch in c#
tableView.SeparatorInset = UIEdgeInsets.Zero;

override func viewDidLoad() {
super.viewDidLoad()
tableView.cellLayoutMarginsFollowReadableWidth = false
}

Related

UItableviewcells with background image not filling the whole width of screen?

Hi i am new for ios and in my app i have created one UITableView and i have set background image for UITableViewcell but image not filling the whole width of screen as like below screen. Why this problem is occuring?
I mean UITableViewCell left and right sides gap is coming images is not filling whole cell width.
please help me someone
my code:-
#import "TableViewController.h"
#interface TableViewController ()
{
UITableView * tableList;
TableCell * Cell;
}
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
tableList = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, [[UIScreen mainScreen]bounds].size.height) style:UITableViewStylePlain];
tableList.delegate = self;
tableList.dataSource = self;
tableList.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:tableList];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"MyCell";
Cell = (TableCell *)[tableList dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (Cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableCell" owner:self options:nil];
Cell = [nib objectAtIndex:0];
}
//UIImageView *imageBackground = [[UIImageView alloc] init];
if (indexPath.row == 0) {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_top.png"];
} else if (indexPath.row == 9) {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_bottom.png"];
} else {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_middle.png"];
}
//imageBackground.contentMode = UIViewContentModeScaleToFill;
//Cell.backgroundView = imageBackground;
return Cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 44.0;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
#end
Try to set the layoutMargins property of the cells and the UITableView to UIEdgeInsetsZero.
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
tableList.layoutMargins = UIEdgeInsetsZero;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[...]
Cell.layoutMargins = UIEdgeInsetsZero;
return Cell;
}
Also check for the contentMode of the UIImageview.
Cell.backGroundImage.contentMode = UIViewContentModeScaleAspectFill;
try set contentInset on Left = 0
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
Use Debug View Hierarchy to figure out UITableView, UITableViewCell or UIImage is not filling the whole width of screen
http://www.raywenderlich.com/98356/view-debugging-in-xcode-6
Please check your "TableCell" in the storyboard. Did you select custom insets option for your custom cell?
Rather than setting up your table view with code, you want to do this in a storyboard. Then you'll want to use auto layout to connect constraints from the table view to the view controller's view. There are lots of tutorials available to teach you how to do this. Learning this will make things much easier in the long run.
Change the name of your tableList property to tableView. That will make more sense to other developers (including yourself in the future), since that's what it is (a UITableView instance).
Your cell is named Cell with a capital C, but you don't want to name properties with capital letters. Also, it doesn't need to be a class property the way it's being used. Remove it from the #interface section.
Coding Guidelines for Cocoa
Remove the -numberOfSectionsInTableView: method. The default is 1, so you don't need code to return the default value.
Instead of -dequeueReusableCellWithIdentifier:, use -dequeueReusableCellWithIdentifier:forIndexPath:. Then you won't need to follow it with a test to see if a cell was returned (it always will be). You'll need to register your nib with -registerNib:forCellReuseIdentifier:. Or better yet, just design it in the storyboard.
It appears that your custom table view cell has a UIImageView named backGroundImage. That should be added as a subview to the cell's backgroundView property (which you'll need to create - the view, not the property, which is already part of UITableViewCell). Set the image view's autoresizingMask so it will resize with the backgroundView:
- (void)awakeFromNib
{
[super awakeFromNib];
self.backgroundView = [[UIView alloc] initWithFrame:self.bounds];
self.backGroundImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.backGroundImage.frame = self.backgroundView.bounds;
[self.backgroundView addSubview:self.backGroundImage];
}
Remove the -tableView:heightForRowAtIndexPath: method. You only want to use this if you return different values. The default row height is 44.0, so you don't need to do anything else.

uitableviewcell separator line not displaying in full width

I am trying to display UITableview custom cell. but my tableview separator does not displaying as expected. I am attaching a screenshot.
I tried with making UIEdgeInsetZero but it did not worked. can anyone help me to fix this.
Setting separatorInset to UIEdgeInsetZero is not enough for iOS 8. You should also set layoutMargins property of table and cell to UIEdgeInsetZero.
Please kindly change the separator insets by custom. Thanks.
Try this:
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;
Hey All I got the solution.
I override layoutSubviews in my Custom UITableViewCell and the separators are displayed properly.
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:#"SeparatorView"]) {
subview.hidden = NO;
}
} }
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove seperator inset
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
// Prevent the cell from inheriting the Table View's margin settings
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
// Explictly set your cell's layout margins
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}

TableView Seperator line gets added to the section header view, what to do?

I got a table view with two sections, no crazy code, just my delegate methods.
It works pretty fine, like i want it to work. It should just look like on this screenshot:
Now the problem is: Sometimes while scrolling or flicking the scoll view to the bounds, this happens (if you can't see it: There is 1 or 1/2 pixel in gray on the top of the second section header, what is not intended to be so):
So, is this a iOS 7.1 or 7.x bug? I'm not using a custom view for the header. Does anyone know how to fix this?
Feedback really is appreciated.
I had this same problem that I battled for a few weeks, and the way I solved it was to set the tableView's separatorStyle to UITableViewCellSeparatorStyleNone, and add a custom subview that is a line to the cell's contentView.
Then in your cellForRowAtIndexPath method, hide the line subview of the last cell in the section:
- (UIView *)lineView
{
// Your frame will vary.
UIView *colorLineView = [[UIView alloc]initWithFrame:CGRectMake(82, 67.5, 238, 0.5)];
colorLineView.backgroundColor = [UIColor blackColor];
return colorLineView;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *identifier = #"cellIdentifier";
UIView *lineView = [self lineView];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
[cell.contentView addSubview:lineView];
}
if (indexPath.section == 0)
{
if (indexPath.row == keys.count -1)
{
lineView.hidden = YES;
}
}
return cell;
}
It may be recycling one of the cell views with the separator from the scroll. This is a long shot, but what if you were to try tweaking the footer view for the section by returning an empty view?
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [[UIView alloc] init];
}
It's also a good trick for removing empty cells from the table when you have only a couple rows.
I tried it with multiple different things and the cleanest approach i found is this.
I created a custom view for the header, but wanted it to look the same as the original not modified header:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 34)];
[headerView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, tableView.frame.size.width, 34)];
[label setFont:[UIFont boldSystemFontOfSize:14]];
if (section == 0) {
NSMutableArray *difficultyArray = [dictionary objectForKey:#"Difficulty"];
NSString *difficulty = [difficultyArray objectAtIndex:0];
[label setText:[NSString stringWithFormat:#"Time Challenge (%#)", difficulty]];
} else {
[label setText:#"Freeplay (5x5 board)"];
}
[headerView addSubview:label];
return headerView;
}
Now we got the sections as they would appear without custom header views, but the bug still exists. I made it simple and clean:
UIView *lineFix = [[UIView alloc] initWithFrame:CGRectMake(0, 77.5, self.tableView.frame.size.width, 0.5)];
lineFix.backgroundColor = [UIColor groupTableViewBackgroundColor];
[self.tableView addSubview:lineFix];
Now we set a view over the buggy seperator with a height of 0.5 pixel, the seperator isn't visible anymore. Between the two section headers now is a 0.5 height view what shouldn't be there, but since i set it the same color as the section background color it isn't noticeable. The view moves, because it is a subview of the tableview, the same direction like the tableview.
If you have questions, just add a comment.

layoutSubviews in UIViewTableCell does not work

I have a class PostListTableCell, inheriting UITableViewCell, which is used as my custom cell in a UITableView.
I need to resize some labels in the cell, so I called following method in
- (void)layoutSubviews {
[super layoutSubviews];
[_titleLabel sizeToFit];
}
But the problem is, when the UITableView loaded, the _titleLabel does not resize:
But after I click this cell and select it, the title did resize:
Following is the code to load data:
- (PostListTableCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *PostListTableCellIdentifier = #"PostListTableCell";
PostListTableCell *cell = (PostListTableCell*) [tableView dequeueReusableCellWithIdentifier:PostListTableCellIdentifier];
if (cell == nil) {
cell = [[PostListTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PostListTableCellIdentifier];
}
Post *post = (Post*)_posts[indexPath.row];
[cell loadPost:post];
return cell;
}
Could anyone help?
The problem is the autolayout that resize again the label for you with the constraints that you had set when you make the label in Interface Build, unfortunately in under autolayout the the hierarchy is Constraints > Frame
First of all, if you use Autolayout in (viewDidLoad) method which is related to UIViewController and its subclasses and (awakeFromNib) which is related to UIView and UITableViewCell etc all Views Frames' have not been rendered yet while those methods called.
So if you want to resize any of outlets you should call it in (ViewDidAppear) for UIViewController. In UIViews and cells you should use:
- (void)layoutSubViews
{
[super layoutSubviews];
}
And don't forget to set interval to your Method of resizing as in this answer.
set frame for your label
-(void)layoutSubviews
{
CGRect frame = CGRectMake(20, 30, 200, 50);
_titleLabel.frame = frame;
}

UITableView separator line disappears when selecting cells in iOS7

In my tableView I set a separator line between cells. I am allowing selection of multiple cells. Here's my code for setting selected cell background color:
UIView *cellBackgroundColorView = [[UIView alloc] initWithFrame:cell.frame];
[cellBackgroundColorView setBackgroundColor:[UIColor darkGray]];
[cell setSelectedBackgroundView:cellBackgroundColorView];
The problem is that if two adjacent cells are selected, there is no separator line between them in iOS7, while there is (as expected) in iOS6.
I even tried setting cellBackgroundColorView's frame height to that of cell.frame - 1.0, but that doesn't work either.
Any ideas?
I haven't gotten to the bottom of it yet (at first glance it seems like an iOS 7 bug..), but I have found a workaround. In tableView:didSelectRowAtIndexPath, if you send both messages below, the issue is visually resolved (with the probable performance cost).
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
For this to work (for me), deselectRowAtIndexPath:animated: must contain animated:YES. The animation used for reloadRowsAtIndexPaths:withRowAnimation: doesn't matter.
Add this code at cell for row at indexpath
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.backgroundColor = [UIColor clearColor];
in my case i was animating a row, so just i needed put some like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
//if you are doing any animation you have deselect the row here inside.
[tableView endUpdates];
}
#samvermette's answer solved the issue for me, But I had to deselect the selected Row first.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Deselect Row
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
// fix for separators bug in iOS 7
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; }
I encountered this issue when I set my cell's selection style to none programatically, and then when I SELECT my table cells programatically.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell!
if tableView == self.jobLevelTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! CheckboxCell
// for testing purposes
let checked = true
// I used M13Checkbox here, in case anybody was wondering
cell.checkbox.setCheckState(checked ? .checked : .unchecked, animated: false)
if checked {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
}
// CULPRIT
cell.selectionStyle = .none
return cell
}
cell = UITableViewCell()
return cell
}
When I set the selection style on the storyboard (and removing the code equivalent), the problem went away!
Past it in your UITableViewCell class.
override func layoutSubviews() {
super.layoutSubviews()
subviews.forEach { (view) in
if type(of: view).description() == "_UITableViewCellSeparatorView" {
view.alpha = 1.0
}
}
}
This still seems to be a problem as of iOS 7.0.3, but I've worked around it with an unsophisticated means of faking the separator.
By first setting the UITableView's separator style to UITableViewCellSeparatorStyleNone. You can then use a custom UITableViewCell subclass to fake the separator between cells for both selected and unselected states:
#implementation MyTableViewCellSubclass
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
CGRect frame = self.bounds;
frame.origin.y = frame.size.height - 1.f;
frame.size.height = 1.f;
// Selected background view
//
UIView * separatorView = [[UIView alloc] initWithFrame:frame];
separatorView.backgroundColor = [UIColor darkGrayColor];
separatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
UIView * selectedView = [[UIView alloc] initWithFrame:self.bounds];
selectedView.backgroundColor = [UIColor lightGrayColor];
[selectedView addSubview:separatorView];
self.selectedBackgroundView = selectedView;
// Add separator view to content view for unselected state
//
UIView * separatorView2 = [[UIView alloc] initWithFrame:frame];
separatorView2.backgroundColor = [UIColor darkGrayColor];
separatorView2.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
[self.contentView addSubview:separatorView2];
}
return self;
}
#end
This simple call did it for me on iOS 8.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// ....
[tableView deselectRowAtIndexPath:indexPath animated:YES]
// ....
}
This'll just happen if you let iOS apply its own default selected cell style. Best work around I found so far is to override the selected property implementation:
in your cell subclass implementation:
#synthesize selected = _selected;
in the initialization method:
// problem actually is caused when you set following
// to UITableViewCellSelectionStyleDefault, so:
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
overriding methods:
- (BOOL)selected
{
return _selected;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
_selected = selected
if (selected) {
// apply your own selected style
}
else {
// apply your own deselected style
}
}
I resolved this issue (hackishly) by reloading not just the selected cell but by also reloading the one right above it. None of the other solutions above worked for me.
NSIndexPath *indexPathOfCellAbove = [NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section];
if (indexPath.row > 0)
[self.tableView reloadRowsAtIndexPaths:#[indexPathOfCellAbove, indexPath] withRowAnimation:UITableViewRowAnimationNone];
else
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
- cellForRowAtIndexPath
Create two separator views (sv1, sv2)
[cell addsubview:sv1];
[cell.selectedBackgroundView addsubview:sv2];
- didSelectRowAtIndexPath
[tableView deselectRowAtIndexPath:indexPath animated:NO];
In iOS 14, Apple has FINALLY made this less painful.
If you want to...
...be able to select rows (for example in edit mode)
...prevent the default gray or blue cell highlight color
...keep the default system separator views
...this will help you. In your UITableViewCell subclass, put this into the initializer:
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Prevent cell highlighting while preserving selectability and separator views
if #available(iOS 14.0, *) {
var backgroundConfig = UIBackgroundConfiguration.listPlainCell()
backgroundConfig.backgroundColor = .clear
backgroundConfiguration = backgroundConfig
} else {
selectedBackgroundView = {
let bgView = UIView(frame: .zero)
bgView.translatesAutoresizingMaskIntoConstraints = false
bgView.backgroundColor = .clear
return bgView
}()
}
}
If you're only targeting iOS 14+ you can leave out the else block and you're done. If you are also targeting iOS 13 and below, you'll also need to override layoutSubviews to keep the separator view from disappearing (thanks to this comment: https://stackoverflow.com/a/47573308/171933). This will do the trick (also in your UITableViewCell subclass):
override func layoutSubviews() {
super.layoutSubviews()
if #available(iOS 14.0, *) {
// no op
} else {
// Setting a custom selectedBackgroundView causes the system to hide the
// separatorView. If we want to have the separator, we need to show it again.
subviews.forEach { view in
if type(of: view).description() == "_UITableViewCellSeparatorView" {
view.alpha = 1.0
}
}
}
}
Enjoy.
For me it happened when I set programmatically:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
When i set this property in the storyboard it works fine.
You could also trying setting the separator insets to 0. I did that and it solved the problem, but the trade-off is you lose the nice look of the insets.
This problem exists for single cell selection as well.
Another solution is to reload the table view, select followed by deselect:
self.selectedIndex = inIndexPath.row;
[inTableView reloadData];
[inTableView selectRowAtIndexPath:inIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[inTableView deselectRowAtIndexPath:inIndexPath animated:YES];
This gets rid of a subtle graphical selection glitch I saw in Mark's solution.
this solution will not help anybody who isn't using a backgroundView on his cells, anyway:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setBackgroundColor:[UIColor grayColor]];
}
this way the annoying visual effect is vastly reduced without having to reload the table.
of course, you can change grayColor with anything which helps you improve the result in your case
use this:
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = [UIColor clearColor];
cell.selectedBackgroundView = selectionColor;
//71
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 71, 320, 2)];/// change size as you need, where - 71 - y coordinate, 320 - weight, 2 - height
// separatorLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"divider_goriz.png"]];// you can also put image here
separatorLineView.backgroundColor = [UIColor redColor];
[cell.selectedBackgroundView addSubview:separatorLineView];
return YES;
}
What I did was this:
Add a new subview under the content view of the cell.
Connect that from the cell as the selectedBackgroundView.
Add a subview of the new selected background view. Set it to start 16px from the left and cover the rest of the width, be 1px high, 1px down from the top and have a background color of 90% white.
In my case, I didn't want my rows shaded at all when selected, so I left the selected background view clear, but you can make it whatever color you like.
Also, I am not using autolayout, so just set my sizes appropriately. I presume with autolayout you would have to set up appropriate constraints.
For me, this completely resolved the problem (though I agree that this really does seem to be a bug in ios 7).
Too exciting, I solved this problem.
Add the following method call in a custom cell, and to set the color separator and frame. I'll hide the cell separator, and then customize the view on a load separator in superview. The impact separator cell is selected when this problem is solved friends
#interface MyCustomTableViewCell(){
UIView *customSeparatorView;
CGFloat separatorHight;
}
#property (nonatomic,weak)UIView *originSeparatorView;
#end
-(void)setSeparatorWithInset:(UIEdgeInsets)insets{
if (customSeparatorView) {
customSeparatorView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, self.originSeparatorView.height-insets.bottom - insets.top);
self.originSeparatorView.hidden = YES;
self.originSeparatorView.alpha = 0;
}else{
for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) {
UIView *subView = self.contentView.superview.subviews[i];
if ([NSStringFromClass(subView.class) hasSuffix:#"SeparatorView"]) {
self.originSeparatorView = subView;
subView.hidden = YES;
subView.alpha = 0;
subView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, subView.height-insets.bottom - insets.top);
customSeparatorView = [[subView superview] viewWithTag:separatorViewTag];
if (!customSeparatorView) {
customSeparatorView = [[UIView alloc] initWithFrame:subView.frame];
customSeparatorView.tag = separatorViewTag;
[[subView superview] addSubview:customSeparatorView];
customSeparatorView.backgroundColor = [subView backgroundColor];
}
[[subView superview] bringSubviewToFront:customSeparatorView];
break;
}
}
}
}
-(void)setSeparatorColorWithColor:(UIColor *)sepColor{
if (customSeparatorView) {
customSeparatorView.backgroundColor = sepColor;
self.originSeparatorView.hidden = YES;
self.originSeparatorView.alpha = 0;
}else {
for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) {
UIView *subView = self.contentView.superview.subviews[i];
if ([NSStringFromClass(subView.class) hasSuffix:#"SeparatorView"]) {
self.originSeparatorView = subView;
if (sepColor) {
subView.hidden = YES;
subView.alpha = 0;
subView.backgroundColor = sepColor;
customSeparatorView = [[subView superview] viewWithTag:separatorViewTag];
if (!customSeparatorView) {
customSeparatorView = [[UIView alloc] initWithFrame:subView.frame];
customSeparatorView.tag = separatorViewTag;
[[subView superview] addSubview:customSeparatorView];
customSeparatorView.backgroundColor = [subView backgroundColor];
}
[[subView superview] bringSubviewToFront:customSeparatorView];
}
break;
}
}
}
}
-(void)layoutSubviews{
[super layoutSubviews];
[self setSeparatorWithInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[self setSeparatorColorWithColor:[UIColor colorWithRed:31/255.0 green:32/255.0f blue:35/255.0 alpha:0.2]];
}
what solved the issue for me was reloading the data after beginUpdates and endUpdates:
private func animateCellHeighChangeForTableView(tableView: UITableView, withDuration duration: Double) {
UIView.animateWithDuration(duration) { () -> Void in
tableView.beginUpdates();
tableView.endUpdates();
tableView.reloadData();
}
}
I needed the following:
"When user selects row, selection background color is
transparent/white/whatever you may call it and separator lines don't
disappear"
I've looked as well for a solution for the following problem:
"When I select a row in a table (plain type table) I had selection
colour grey, and if I set cell.selectionStyle to none -> Separators
between cells disappeared."
Xcode - 9.2 version
Found the following solution:
in 'tableView (....cellForRowAT...)'
let colorView = UIView(frame: CGRect(x: 0.0, y: 3.0, width:
cell.frame.width, height: cell.frame.height - 1.0))
colorView.backgroundColor = UIColor.white
UITableViewCellClass.appearance().selectedBackgroundView = colorView
UITableViewCellClass - is your prototype cell class
it makes possible to change selection color to white
in 'tableView (...didSelectRowAt)'
cell.selectionStyle = .none
in UITableViewCellClass (your prototype cell class)
override func layoutSubviews() {
super.layoutSubviews()
subviews.forEach { (view) in
if type(of: view).description() == "_UITableViewCellSeparatorView" {
view.alpha = 1.0
}
}
}
it allows to keep selected row with check mark and all separators are in place.
The solutions here didn't help me. In most cases it was proposed to remove the selection, but I wanted the cells to keep their selected state. So the idea is to disable the default separator line and use your own separator line. I tried this but I had problems with it (you can read more about this here). The main problem was drawing the line in the accessoryView area. It only worked on iOS 8, but I also needed a solution for iOS 7.
My requirements were:
Selection should be kept
Line should not disappear (especially in the case the cell get selected)
Separator line above the selected cell should also not disappear
Especially the third point made problems because iOS uses a kind of anti-aliasing effect for the crossing of on UITableViewCell to the next. As I found out that only occurs on iPad. It has the size of about one point in each direction (current selected cell, cell above) so that a line on the cell disappears even it is drawn on the cell itself (and not the default one used). It makes no difference if this line is on the cell above or on the selected cell. This special render effects hides my lines.
The solution looks like the following:
Use the backgroundView where you draw two lines: one on top (+1 point in y-direction for iPad and 0 point in y-direction for iPhone) and one on the bottom. So it never gets covered by the selection effect.
The created background view should only be used for the selected state (cell.selectedBackgroundView = selectedBackground). The default separator line is enabled for the other cells.
I have a working example with C# code posted here though you have to adapt it to your needs. Now my selection problems are gone!
I encountered this problem with IOS 13 and solved it in this way:
In tableView cell storyboard or xib file choose Selection NONE
In swift file of the cell override func:
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
if highlighted {
contentView.backgroundColor = .lightGray
} else {
contentView.backgroundColor = .clear
}
}
I wanted to get effect of regular selection like in previous IOS versions but if you want to get something else then customize the function with your colors.
For those of you looking for a solution in Swift, this fixed the issue for me. In your cellForRowAtIndexPath method, after you call dequeueReusableCellWithIdentifier, you just need to set the cells selectionStyle to .None
Here's the code:
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:TextTableViewCell = tableView!.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! TextTableViewCell
cell.selectionStyle = .None // This fixes the disappearing border line issue

Resources