UITableViewCell selectedBackgroundView does not work - ios

My UITableViewCells are all pre-defined "Subtitle" style. I want to set the background image for a selected cell to another picture. I tried every which way to implement this and all methods discussed on stackoverflow seem to fail.
I tried again for some other, easier way to change the selectedBackgroundView property, like:
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds] ;
cell.selectedBackgroundView.backgroundColor = [UIColor yellowColor];
But it doesn't work as well. What's wrong with that ?

As I understand you want to set selected background image to your cell?
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"backgroundImage.png"]];
EDIT:
As i know UITableViewCell can not be highlighted after selection in such common cases:
There is somewhere set cell.selectionStyle = UITableViewCellSelectionStyleNone;
You implemented willSelectRowAtIndexPath and it returns nil;
There is set [self.tableView setAllowsSelection:NO];
May be you set self.tableView.userInteractionEnabled = NO; or cell.userInteractionEnabled = NO;
You subclassed UITableViewCell and implemented such methods not correct setSelected:animated: or setHighlighted:animated
May be share your cellForRowAtIndexPath method code to investigate the problem

You can change the highlight color in several ways.
Change the selectionStyle property of your cell. If you change it to UITableViewCellSelectionStyleGray, it will be gray.
you can also check that property in your tableView:didSelectRowAtIndexPath:
//do something like this for color
cell.selectionStyle= UITableViewCellSelectionStyleGray;
// for image
cell.selectedBackgroundView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"imageName"]];
Change the selectedBackgroundView property. Actually what creates the blue gradient is a view. You can create a view and draw what ever you like, and use the view as the background of your table view cells.
best of luck..

In my case the problem appeared after compiling on Xcode 13 - sdk iOS 15+
with any change to the code. Eventually I subclassed the cell and add the code:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self.contentView insertSubview:self.selectedBackgroundView
atIndex:0];
self.selectedBackgroundView.hidden = !selected;
}

Related

Change the selected cell background colour using UIAppearance

I need to change the selected cell background colour for all the cells in my app. As I know there is a way to use UIAppearance protocol for this purposes. Is it possible to realize this by the category for UITableViewCell?
Using appearance proxy you can colour all cells. Don't know if you can target specific category.
To do the colouring put following code in your AppDelegate.m file:
Put [self customCellBackground];
in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions
and somewhere at the end:
- (void)customCellBackground {
UIView *cellBackgroundView =[[UIView alloc] init];
cellBackgroundView.backgroundColor = [UIColor blackColor];
[[UITableViewCell appearance] setSelectedBackgroundView:cellBackgroundView];}
As null's answer is not for selected cell backgrounds and Armands L.'s answer did not work consistently for me (selecting cells by 'user-tap' did work, but programmatical cell selection showed strange results (like sometimes the selected background was not visible, or did not fill the cell's height properly...).
I found a custom solution that worked:
Subclass UITableViewCell
Initialize self.selectedBackgroundView in init and
Add custom UIColor property with UI_APPEARANCE_SELECTOR for custom selected background color
.h file:
#property (nonatomic) UIColor* selectedCellBackgroundColor UI_APPEARANCE_SELECTOR;
.m file:
in init method(s):
self.selectedBackgroundView = [[UIView alloc] init];
and last but not least the setter function for the color:
- (void) setSelectedCellBackgroundColor:(UIColor*) color {
_selectedCellBackgroundColor = color;
self.selectedBackgroundView.backgroundColor = color;
}
You can't do this direct to UITableViewCell, but you can do it for its contentView:
[[UIView appearanceWhenContainedIn:[UITableViewCell class], nil] setBackgroundColor:[UIColor redColor]];
Note that it will change all the subViews bg color.
Another option is writing a category or subclass the UITableViewCell with UI_APPEARANCE_SELECTOR mark, check this question:
iOS: Using UIAppearance to define custom UITableViewCell color

Changing Background of Edit Button - UITableView iOS7

I have a UITableView which when edited looks as follows :
Is it possible to somehow change the background behind the delete symbol so that it is not white ?
I hope this help you
UIView *cellBackView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
cellBackView.backgroundColor = [UIColor clearColor];
cell.cellBackgroundView = backView;
The problem ist that contentView gets shifted to the right when you are in editing mode, and because of this all its subviews will move to the right as well.
If your background is an imageView you should not add is as subview to contentView, set it as backgroundView of the cell instead.
Since you can't setup backgroundView from interface builder I would recommend to create a custom subclass of your cell and put the background creation into awakeFromNib.
- (void)awakeFromNib {
[super awakeFromNib];
self.backgroundView = [[UIImageView alloc] initWithImage:...];
}

Dimming a tintColor on a UITableViewCell

Here is a UITableViewCell that opens a modal ('Add Ingredients'):
I am setting the label color to match the application's tintColor:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = #"Add Ingredients...";
cell.textLabel.textColor = [self.view tintColor];
How do I dim the text color when a UIAlertView or UIActionSheet is presented? This behavior is default for buttons and other controls, but not for a cell's text label.
I have found references to tintAdjustmentMode and tintColorDidChange, but do not know how to use either.
Or should I be adding a button to my cell? My previous experience with this approach wasn't optimal - there were side-efffects with responsiveness.
I believe you are correct. You should just be able to override the tintColorDidChange method in your CustomUITableViewCell.
http://www.qubop.com/ios7.pdf

iOS - Custom UITableViewCell subviews within selectedBackgroundView

I have set up a custom UITableViewCell with multiple labels and an image, and I've (finally) got it to look how I want it to look.
I can't seem to figure out how to get the selection to look how I want it to look, however. I have implemented the setSelected method, which allows me to change the background color just fine, but what I would really like is to set the background color to black and display a colored rectangle on the left-hand side of the selected cell (10 pixels wide and the height of the cell).
The colored box would be a color set programmatically, so although I could easily set the selectedBackgroundView to be a UIImageView, this will not work in this case.
The following code will not display the selectedViewColor UIView at all when the cell is selected:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
UIView *selectedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.selectedBackgroundView.bounds.size.width, self.selectedBackgroundView.bounds.size.height)];
[selectedView setBackgroundColor:[UIColor blackColor]];
UIView *selectedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, self.selectedBackgroundView.bounds.size.height)];
[selectedViewColor setBackgroundColor:[UIColor redColor]];
[selectedView addSubview:selectedViewColor];
self.selectedBackgroundView = selectedView;
[super setSelected:selected animated:animated];
}
This code seems pretty basic, so I assume there is an issue with displaying any type of subview within the selectedBackgroundView.
Any alternatives or advice would be greatly appreciated.
There's a few things that could be done better with this code. Reinitialising two views in the setSelected method is pretty inefficient. You're actually blanking out everything in the cell when you select it with this code (which I'm guessing is not what you want). And finally, you're treating selectedBackgroundView as if it's the only view that gets displayed when you select the cell (according to Apple's documentation, it is displayed over the backgroundView).
Try the following (Edited) -
Put this code where you create the cell (presumably, cellForRowAtIndexPath:)
UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.backgroundView.bounds.size.width, cell.backgroundView.bounds.size.height)]; // we need this because in cells, the background views always take up the maximum width, regardless of their frames.
container.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0]; // make it transparent - we only want the square subview to be seen.
UIView *selectedViewColor = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, self.selectedBackgroundView.bounds.size.height)];
[selectedViewColor setBackgroundColor:[UIColor redColor]];
[container addSubview:selectedViewColor]
cell.selectedBackgroundView = container;
This will make your red square appear when (and only when) the cell is selected, over the other views in the cell. From Apple's docs:
UITableViewCell adds the value of this property as a subview only when the cell is selected. It adds the selected background view as a subview directly above the background view (backgroundView) if it is not nil, or behind all other views.
Second, use the following code in your cell:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected == YES)
{
self.backgroundView.backgroundColor = [UIColor blackColor];
}
else
{
self.backgroundView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0] // replace this with whatever's appropriate - a return to the unselected state.
}
}
This will ensure that your background turns black when the cell is selected (without otherwise interfering with what's displayed. Hopefully these changes should also resolve the issue you're having.
In addition to Xono's answer above, following up on his comment on the answer above:
One thing I've come across a couple of times while researching this subject is a possibility that the code behind UITableViewCell may actually set the backgroundColor of all subviews to transparent when a cell is selected.
It does indeed do this if your cell's SelectionStyle is anything but None. And it does it in both the setHighlighted and setSelected calls of UITableViewCell.
My first solution was to subclass UITableViewCell and override both these methods, not calling the base class method and doing my own animations. This is not ideal as your now re-implenting (probably badly) standard iOS animations.
Looking into it further though, the standard methods animate the opacity of the whole view, not the subviews (they only set the color of the subviews). So the best approach is to still call the base class methods, and then just re-set your subview colors back to whatever they should be. Even though your setting them instantaneously, because their superview is still animating its opacity, it still fades in and out correctly:
public override void SetHighlighted(bool highlighted, bool animated)
{
base.SetHighlighted(highlighted, animated);
SelectedBackgroundView.Subviews[0].BackgroundColor = SelectionColor;
}
public override void SetSelected(bool selected, bool animated)
{
base.SetSelected(selected, animated);
SelectedBackgroundView.Subviews[0].BackgroundColor = SelectionColor;
}
This is c# MonoTouch code, but it applies equally well to obj-c.
Note that in my case I always have exactly 1 subview, hence the hardcoded 0 indexer. This may differ depending on your view structure.
You can override method "setBackgroundColor" for your subviews and add another method with the same functionality. At this case UITableCell won't be able to change backgroundColor after selection.
- (void)setBackgroundColor:(UIColor *)backgroundColor {
}
- (void)setColor:(UIColor *)color {
[super setBackgroundColor:color];
}
Basing on #Xono 's answer, I made this solution to the problem:
Inside of the initWithStyle:reuseIdentifier: method I added a separator view:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
CGRect selectionViewFrame = self.contentView.bounds;
UIView *selectionView = [[UIView alloc] initWithFrame:selectionViewFrame];
[selectionView setBackgroundColor:[UIColor colorWithWhite:1. alpha:0.65]];
self.selectedBackgroundView = selectionView;
self.vwSelectedSeparator = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 1.)];
[self.vwSelectedSeparator setBackgroundColor:[UIColor colorWithHexString:#"aaa"]];
[self.vwSelectedSeparator setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[selectionView addSubview:self.vwSelectedSeparator];
[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
}
return self;
}
And then in setSelected:animated: method I added these lines:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
if (selected) {
[self.vwSelectedSeparator setBackgroundColor:[UIColor colorWithHexString:#"aaa"]];
}
}
Works like a charm for both ios6 and ios7 for me. I hope this helps.

Transparent background for the Group Table Cell

For group table cell, I fall into this problem.
cell.backgroundColor=[UIColor clearColor]
make the cell bg black. It works for normal cell, not for group table cell.
I want to add some button, e.g. like the detail view of iPhone contact with transparent background.
If anybody face the problem, I got a solution, set a transparent view as a background view of the cell. Then it becomes totally transparent. Then you can add more view or customize the cell.
UIView *backView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
backView.backgroundColor = [UIColor clearColor];
messageCell.backgroundView = backView;
messageCell.contentView.layer.cornerRadius = 10.0;
messageCell.contentView.layer.borderWidth = 1.0f;
messageCell.contentView.layer.borderColor = [[Settings getInstance] colorFrameBorder].CGColor;
messageCell.selectionStyle = UITableViewCellSelectionStyleNone;
return messageCell;
This solution was quoted in one of the StackOverflow question, which I cant remember.
I have also found that, its easy to add a transparent view in the table header or footer. The button down the contact details are probably added in a footer view.
From the looks of it I'd say you are setting a background image to your cell. You can see it at each cell on the right side, there are the stripes from your view background.
Remove the cell's background and you should be fine.
I found the solution from this answer here by setting cell's backgroundView
cell.backgroundView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
I would take Charles's answer one step further and do the following
self.myTableView.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];

Resources