custom UITableViewCell reuse highlight issue - ios

in the project I'm on, there is already a custom UITableViewCell and I have determined the issue is in the reuse of the cell.
These 2 methods are doing the overriding of the highlighting and selecting:
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
if (self.isCellEditing == NO) {
if (highlighted) {
self.customView.backgroundColor = [UIColor redColor];
} else {
self.customView.backgroundColor = [UIColor whiteColor];
}
}
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
if (self.isCellEditing == NO) {
if (selected) {
self.customView.backgroundColor = [UIColor redColor];
} else {
self.customView.backgroundColor = [UIColor whiteColor];
}
} else {
if (selected) {
self.editImageView.image = self.editAccessorySelectedImage;
} else {
self.editImageView.image = self.editAccessoryImage;
}
}
}
what's happening in the app that is causing the issue is that I need to auto-scroll and select the last selected cell before the app closed on app launch (done in viewDidAppear). This works, except for highlighting the cell, it does in fact scroll to the cell selects it, as it shows in the details view (iPad splitview setup), but the cell will not highlight. This is a reuse issue because if the cell that needs to be scrolled to is one of the first cells that are visible at load, it will highlight but if it's a cell that's off screen and it scrolls to that cell it will select but not highlight it.
ETA: cell reuse override:
- (void)prepareForReuse {
[super prepareForReuse];
self.selectionStyle = UITableViewCellSelectionStyleNone;
_cellEditing = NO;
_swipingToDelete = NO;
_editViewAnimated = NO;
}

In the event anyone else wants a custom highlight and selected state, the fix was:
if (highlighted || self.isSelected)
this will force it to jump inside this if block since when it's selected you want it the color of the highlight and selected state (assuming they're the same color)

Related

Dynamically changing textColor of a UITableViewCell's text

I have a custom UITableViewController that has one row, and only two UITableViewCells.
I'm trying to dynamically set the color of my UITableViewCell's text (cell.textLabel.textColor) based upon a few things:
1) If this is the first time launching, the first cell's text color should be [UIColor whiteColor], and the second cell's text color should be [UIColor grey1Color]
2) If the user selects a cell and leaves the screen and then returns to the table-view, the last selected cell's text color should be [UIColor whiteColor], and text color of the cell that was not selected should be [UIColor grey1Color].
Whenever a cell is selected, a property is updated; myCellTextValue. This is done to make a few API calls outside of this particular table-view.
My idea for implementing the logic above was to use this property for determining what color the cell's text should be. My code attempt below is in cellForRowAtIndexPath:
if (cell.textLabel.text == self.myCellTextValue) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
}
However, both cell's text color is always grey. I'm sure this mostly has to do with misunderstanding UITableViewCell creation in someway. Does anyone have any pointers on how to implement this properly? Thank you!
EDIT: Following #Gismay's comment below, I tried the code below; but got the same result:
if ([cell.textLabel.text isEqualToString:self.myCellTextValue]) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
EDIT 2: I also tried wrapping the code above in a check to make sure we're only looking at one cell at a time, but this had no effect either:
if((indexPath.section==0)&&(indexPath.row==0)){
if ([cell.textLabel.text isEqualToString:self.myCellTextValue]) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
} else if((indexPath.section==0)&&(indexPath.row==1)){
if ([cell.textLabel.text isEqualToString:self.myCellTextValue]) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
}
You can do something like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//change your cell text color here
cell= [tableView cellForRowAtIndexPath:indexPath]
cell.textLabel.textColor = [UIColor whiteColor];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (cell.isSelected == YES)
{
cell.textLabel.textColor = [UIColor grey1Color];
}
else
{
cell.textLabel.textColor = [UIColor whiteColor];
}
}
Another way is to subclass the tableview cell and implement the following methods:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self updateTextColor:selected];
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
[self updateTextColor:highlighted];
}
- (void)updateTextColor:(BOOL)isSelected {
labelA= //get reference of the cell textlabel
if (labelA) {
if (isSelected) {
[labelA setTextColor:[UIColor whiteColor]];
} else {
[labelA setTextColor:[UIColor greyColor]];
}
}
}
you could use selectedRowIndex as a class-level variable, and just keep updating that every time you select a row. Initially - whether selected or not - this should be 0, so that the first row is different
I think you don't want to use the text value because it may not be unique
What happens when you make multiple selections without leaving the view? Presumably you need to clear the white text from the old row, and set it again on the new one?
Easiest way to implement that is going to be reloading the tableView on each selection - but if that takes too long, you could always reload the individual rows - on row selection set selectedRowIndexPrevious before you update selectedRowIndex, and reload both of those rows. The previous row will redraw in grey, and the new one in white
here's how you might implement some of this
class MyViewController : UIViewController
{
// define the variables to keep track of row selection here
var selectedRowIndex : Int = 0
var selectedRowIndexPrevious : Int = -1
// the rest of your code
and then you need to update the selectedRow variables
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Uncheck the previous checked row
selectedRowIndexPrevious = selectedRowIndex
// **UPDATED** need to set the selectedRowIndex
selectedRowIndex = indexPath.row
// **UPDATED**
// reload needs an array of indexPath
// so we can supply the previous selection AND the current one
NSIndexPath* rowToReloadPrevious = [NSIndexPath indexPathForRow: selectedRowIndexPrevious inSection:0];
NSIndexPath* rowToReloadNew = [NSIndexPath indexPathForRow: selectedRowIndex inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReloadPrevious, rowToReloadNew, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
}
within the cellForRowAtIndexPath, you just need to look at selectedRowIndex instead of checking the text
if (indexPath.row == selectedRowIndex) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
}

AsyncDisplayKit CellNode setting highlighted color

I'm using Async Display Kit to display cell nodes in an ASTableView. How can I set a custom color for the cell node's selected state. With normal tableView cells I would just override
(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
in my cell implementation, but that method doesn't exist on ASCellNodes. Has anyone else encountered this problem and how did you solve it?
Assuming you've subclassed ASCellNode to create your own cells, you could just add your own setHighlighted method.
e.g.
- In Your ASCellNode Subclass
- (void)setHighlighted:(BOOL)highlighted {
if (highlighted) {
self.backgroundColor = [UIColor blueColor];
} else {
self.backgroundColor = [UIColor whiteColor];
}
}
- In Your Delegate Implementation
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MyNodeSubclass * node = (MyNodeSubclass *)[(ASTableView *)tableView nodeForRowAtIndexPath: indexPath];
[node setHighlighted: YES];
}
Note:
You'll need to maintain your own state in regards to which cells are selected/deselected

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

cell.accessoryView image appearing when it shouldn't for reusable cells only

I am using custom cells where I set two images, an accessoryView image and some custom buttons. The accessoryView image shows up initially. When the user swipes the row, i hide the accessoryView image and unhide the buttons. When the user 'unswipes' (or taps somewhere else), I hide the buttons and show the accessoryView. This all works fine, except when I do the following:
1)Load the screen. accessoryView image is there and buttons are hidden. Good.
2)Swipe a row. accessoryView disappears and buttons appear. Good.
3)Scroll down the table to reveal more cells (I'm using reusable cells). All new cells are shown with accessoryView and no buttons. Good, as expected.
4)Scroll back up to the original cell I swiped. I see both the accessoryView image and the buttons like this:
Here's some code:
In my custom cell object, I have:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if (selected)
{
self.accessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"arrow-right-black.png"]];
UIImage *selectedRowImage = [UIImage imageNamed:#"table-selectedcellbg-red-45px-stretch.png"];
self.selectedBackgroundView = [[UIImageView alloc]initWithImage:[selectedRowImage resizableImageWithCapInsets:UIEdgeInsetsMake(selectedRowImage.size.height, selectedRowImage.size.width/2, selectedRowImage.size.height, selectedRowImage.size.width/2)]];
}
else
{
self.accessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"arrow-right.png"]];
self.selectedBackgroundView = [[UIImageView alloc]initWithImage:[[UIImage alloc]init]];
}
}
- (void)swipeCell
{
[self setSelected:NO animated:NO];
self.accessoryView = nil;
swipeButtons.hidden = NO;
}
- (void)unswipeCell
{
[self setSelected:NO animated:NO];
self.accessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"arrow-right.png"]];
swipeButtons.hidden = YES;
}
In my cellForRowAtIndexPath, I check to see if the cell was swiped:
if (self.indexPathSwipeButton != nil && self.indexPathSwipeButton.row == indexPath.row)
{
[cell swipeCell];
}
else
{
[cell unswipeCell];
}
return cell;
Any ideas?
You use [self setSelected:NO animated:NO]; in method (void)swipeCell and in method - (void)unswipeCell.
But in (void)swipeCell it should be [self setSelected:YES animated:NO];.
Hope it helps

Custom table view cell selection font color

I have a custom UITableViewCell. It has 3 custom labels inside it with custom text.
When i tap on the cell, i want the textColor of all those labels to go white. just like Email app UITableViewCell behavior.
For that, I wrote this in the custom cell class.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
if (self.selected) {
_subjectLabel.textColor = [UIColor whiteColor];
_messageLabel.textColor = [UIColor whiteColor];
_usernameLabel.textColor = [UIColor whiteColor];
}else {
_subjectLabel.textColor = [UIColor blackColor];
_messageLabel.textColor = [UIColor grayColor];
_usernameLabel.textColor = [UIColor blackColor];
}
}
I was able to get it. But its not as smooth as it is in the Email app. The color changes only after a small delay. Which method of UITableViewCell should I override to put this code in. I know about the below options, but they don't give the behavior onto custom labels in the custom cell.
typedef enum {
UITableViewCellSelectionStyleNone,
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray
} UITableViewCellSelectionStyle;
Set the label's highlightedTextColor and this will all be done for you automatically. You should not have to do anything special in setSelected at all.
e.g.
_subjectLabel.highlightedTextColor = [UIColor whiteColor];
When we select any cell of UITableView , -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method called immediately, you can use this.

Resources