Set background color of UITableViewCell - objective-c

I have looked around to find a solution for setting the background color of the accessoryView to the same background color as the cell´s contentView.
cell.contentView.backgroundColor = [UIColor colorWithRed:178/255.f green:14/255.f blue:12/255.f alpha:0.05];
cell.accessoryView.backgroundColor =[UIColor colorWithRed:178/255.f green:14/255.f blue:12/255.f alpha:0.05];
There is a solution that works but only let me use one color for all cells.
cell.contentView.superView.backgroundColor = [UIColor redColor];
Is the only solution to not use the accessoryView and use an image instead?
Thanks!

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor greenColor];
}
Using this UITableViewDelegate method, you can set the color of cells to different colors. Note that Apple explicitly advise you to make changes to the backgroundColor property within the tableView:willDisplayCell:ForRowAtIndexPath: method in the docs, which state:
If you want to change the background color of a cell, do so in the tableView:willDisplayCell:forRowAtIndexPath: method of your table view delegate
Indeed, in iOS 6, changes to the property from anywhere else (like the tableView:cellForRowAtIndexPath: method) would have no effect at all. That no longer seems to be the case in iOS 7, but Apple's advice to modify the property from within tableView:willDisplayCell:ForRowAtIndexPath: remains (without any explanation).
For alternating colors, do something like this example:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2) {
cell.backgroundColor = [UIColor yellowColor];
} else {
cell.backgroundColor = [UIColor redColor];
}
}

I struggled with this one for a little while too and resorted to creating a custom image with the accessory. But I just found this solution that works well and doesn't require a custom image. The trick is to change the cell's backgroundView color not the backgroundColor.
UIView *myView = [[UIView alloc] init];
if (indexPath.row % 2) {
myView.backgroundColor = [UIColor whiteColor];
} else {
myView.backgroundColor = [UIColor blackColor];
}
cell.backgroundView = myView;
No need to change the accessoryView or contentView background colors. They'll follow automatically.
Note for 2014. Very typically you wold use -(void)setSelected:(BOOL)selected animated:(BOOL)animated
So, you'd have a custom cell class, and you'd set the colours for the normal/selected like this...
HappyCell.h
#interface HappyCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *mainLabel;
etc...
#end
HappyCell.m
#implementation HappyCell
-(id)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
}
return self;
}
-(void)awakeFromNib
{
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected)
{
self.backgroundColor = [UIColor redColor];
.. other setup for selected cell
}
else
{
self.backgroundColor = [UIColor yellowColor];
.. other setup for normal unselected cell
}
}
#end
// to help beginners.......
// in your table view class, you'd be doing this...
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return yourDataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tv
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger thisRow = indexPath.row;
ContentsCell *cell = [tv
dequeueReusableCellWithIdentifier:#"cellName"
forIndexPath:indexPath];
// "cellName" must be typed in on the cell, the storyboard
// it's the "identifier", NOT NOT NOT the restorationID
[cell setupForNumber: thisRow];
cell.mainLabel.text = yourDataArray[ thisRow ][#"whatever"];
cell.otherLabel.text = yourDataArray[ thisRow ][#"whatever"];
return cell;
}
hope it helps someone.

This worked for me:
cell.contentView.backgroundColor = [UIColor darkGreyColor];

For all lines with the same color
cell.backgroundColor = [UIColor colorWithRed:6.0/255.0 green:122.0/255.0 blue:145.0/255.0 alpha:1.0f];
For 2 colors
cell.backgroundColor = [UIColor colorWithRed:6.0/255.0 green:122.0/255.0 blue:145.0/255.0 alpha:1.0f];
if ((cell.backgroundColor = (indexPath.row % 2 == 0 ? [UIColor colorWithRed:6.0/255.0 green:122.0/255.0 blue:145.0/255.0 alpha:1.0f] : [UIColor colorWithRed:2.0/255.0 green:68.0/255.0 blue:80.0/255.0 alpha:1.0f]))){
cell.textLabel.textColor = [UIColor whiteColor];
}

For anyone else who might stumble on this and wants to set their UITableViewCell background to a pattern or texture rather than a solid color, you can do so like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"pattern.png"]];
}

The best option to have different backgrounds and what not would probably be to make your own TableViewCell implementation, in there you can put the logic to show whatever you want based on content or index etc.

Related

UICollectionViewCell: Add a view in cell on tap

I have a uicollectionview and I am trying to add a a view to the collectionview cell when it is tapped.
Here is the code I have tried to implement
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
WeekCell *cell = (WeekCell*)[collectionView cellForItemAtIndexPath:indexPath];
NSLog(#"%#", cell.descLabel.text);
UIView *view = [[UIView alloc]initWithFrame:cell.backgroundView.bounds];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 40, 40)];
label.text = #"new label";
[view addSubview:labels];
view.backgroundColor = [UIColor whiteColor];
[cell.backgroundView addSubview:view];
}
Here WeekCell is a custom UICollectionViewCell with a property view , backgroundview. You will also notice an NSLog in the code. This verifies that the correct cell is being retrieved. What is not working is according to the code, the text should change to white with a new UILabel but this is not the case. The cell's appearance does not change.
EDIT
As suggested I have tried to directly modify the model and call the reloadItemsAtIndexPaths to reload the data. I get an issue where the the "tapped behaviour" is being copied on to untapped cells.
Here is the new code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
if([[modelArray objectAtIndex:indexPath.row] isEqualToString:#"1"]){
cell.overviewView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:imageString]];
}else{
cell.overviewView.alpha = 0;
}
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
WeekCell *cell = (WeekCell*)[collectionView cellForItemAtIndexPath:indexPath];
NSLog(#"%#", cell.descLabel.text);
if([[modelArray objectAtIndex:indexPath.row] isEqualToString:#"1"]){
[modelArray setObject:#"0" atIndexedSubscript:indexPath.row];
}else{
[modelArray setObject:#"1" atIndexedSubscript:indexPath.row];
}
NSLog(#"sequence : %#", modelArray);
[collectionView reloadItemsAtIndexPaths:#[indexPath]];
}
What I am doing is changing the alpha value of the view in the tapped cell to 0. This causes the other cells at random order to disappear once I scroll.
Instead of:
[cell.backgroundView addSubview:view];
... add to content view:
[cell.contentView addSubview:view];
Remarks:
Direct manipulation on collection view cell can cause unexpected results. For instance if cell gets reused. Better to update the model that gets rendered by the cell and call reloadItemsAtIndexPaths: that will automatically(internally) call collectionView:cellForItemAtIndexPath: which should configure(or invoke configuration routine) for the cell that can adjust its presentation.
UPDATE:
You should reset alpha of cells that should be visible, bellow is collectionView:cellForItemAtIndexPath: method with correction:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
if([[modelArray objectAtIndex:indexPath.row] isEqualToString:#"1"]){
cell.overviewView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:imageString]];
cell.overviewView.alpha = 1;
} else {
cell.overviewView.alpha = 0;
}
}
The backgroundView property of a UICollectionViewCell is placed behind the content view. So the reason for the label not being visible could be because it is masked by the content view.
You could set clearColor for the Content view views or add the new view to the contentView;
[cell.contentView addSubview:view];
Hope this information is helpful.

UIcollectionview not displaying data.The numberOfItemsInSection and cellForItemAtIndexPath methods are not firing.How to display data on label?

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return departureTimesArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
User *user = [departureTimesArray objectAtIndex:indexPath.row];
UILabel *label = (UILabel*)[cell.contentView viewWithTag:100];
if (!label)
{
label = [[UILabel alloc] initWithFrame:CGRectMake(12.0, 90.0,90.0, 30.0)];
label.textColor = [UIColor redColor];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:16];
label.textColor = [UIColor colorWithRed:46.0/255.0 green:63.0/255.0 blue:81.0/255.0 alpha:1.0];
label.tag = 100;
[cell.contentView addSubview:label];
}
// label.text=user.departureTime_Bus;
label.text = [NSString stringWithFormat:#"%#",user.departureTime_Bus];
return cell;
}
Custom delegate method
-(void)repaint:(NSMutableArray *)retrievedData
{
if (retrievedData.count > 0)
{
NSLog(#"%#is the value",retrievedData);
userObj = [retrievedData objectAtIndex:0];
[departureTimesArray addObjectsFromArray:retrievedData];
[mycollectionView reloadItemsAtIndexPaths:departureTimesArray];
}
}
Check first this
#interface ViewController : UIViewController "<"UICollectionViewDelegate,UICollectionViewDataSource">"
Second thing is check IBoutlet
#property (nonatomic, strong) IBOutlet UICollectionView *collectionView;
Third one is check
self.collectionView.delegate=self;
self.collectionView.dataSource=self;
These three step must call for datasource and delegate method of collection view.
If the data source or delegate methods aren't firing, it's usually one of a few things:
Your data source or delegate for the collection view aren't set.
Your collection view is so small that a cell cannot fit in it. Both collection and table views only try to create the number of cells that it can display.
If you're using storyboards, make sure your view controller in the storyboard is actually referencing the file you want it to.

How to set background color of a UIImageView from a UICollectionView cell

I have not used UICollectionView much so this may not be possible, but never hurts to ask :)
Each cell is set up as a different color.
What I want to do is tap on a cell and push to another UIViewController that will contain a UIImageView of the same color that was selected.
Right now I can change the color of the second UIViewController's View, but not of the UIImageView within it.
Here's some of my code:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
ImageViewController * imageVC = [[ImageViewController alloc] initWithNibName:#"ImageViewController" bundle:nil];
self.flatColor = [self colorForRow:indexPath.row];
[self.navigationController pushViewController:imageVC animated:YES];
imageVC.colorImageView.backgroundColor = _flatColor;
}
- (UIColor *)colorForRow:(NSInteger)row
{
UIColor *color;
switch (row)
{
case 0:
color = [UIColor redColor];
break;
case 2:
color = [UIColor greenColor];
break;
case 4:
color = [UIColor blueColor];
break;
default:
color = [UIColor yellowColor];
break;
}
return color;
}
EDIT:
Fixed the issue.
I had to rearrange some of the code. The new viewController needs to be completely loaded first and then change the backgroundColor of the UIImageView
Try following code.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
ImageViewController * imageVC = [[ImageViewController alloc] initWithNibName:#"ImageViewController" bundle:nil];
self.flatColor = [self colorForRow:indexPath.row];
// This does not work
[imageVC.colorImageView setBackgroundColor:_flatColor];
//imageVC.colorImageView.backgroundColor = _flatColor;
// This works
//imageVC.view.backgroundColor = _flatColor;
[self.navigationController pushViewController:imageVC animated:YES];
}

How to set footer in one section of TableView manually (iOS)?

I would like to implement some code, which changes footer text in one section of the tableView (in viewDidAppear or viewWillAppear method). But how can I do it?
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
doesn't fit my requirements (It changes only once, during load of the tableView, but I need to change the footer's text after text in tableView cell is changed.
-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 120;
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return #"Things We'll Learn";
} else {
return #"Things Already Covered";
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[tableView reloadData];
}
Implement viewForFooterInSection and add your textField there. Also make that textField a property.
When you have finished editing you tableViewCells, implement the textFieldDidEndEditing method and assign necessary value to the textField of your footerView.
Once your textField is set, use [tableView reloadData] to implement the viewForFooterInSection again and it should work now.
Edit:
If you want to change the title of the Footer section after editing the UITableViewCell,
Set a global variable or use NSUserDefaults to indicate that tableViewCell has been edited.
self.tableView reloadData right after edit.
In the method titleForFooterInSection check for that variable (this would mean that tableView has been edited) and set the title accordingly.
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if(section == 1)
{
// For Lable
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 40)] autorelease];
tableView.sectionHeaderHeight = view.frame.size.height;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, view.frame.size.width - 20, 44)];
label.text = [self tableView:tableView titleForHeaderInSection:section];
label.font = [UIFont boldSystemFontOfSize:16.0];
label.shadowOffset = CGSizeMake(0, 1);
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.adjustsFontSizeToFitWidth = YES;
[label setLineBreakMode:NSLineBreakByTruncatingTail];
[label setNumberOfLines:0];
label.text = #“Your Text Here…..your Text Here”;
[view addSubview:label];
[label release];
return view;
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if(section == 1)
{
return 60.0;
}
return 0;
}

UITableViewCell background color problem

I subclassed UITableViewCell to set a cell background color to a color I need:
.h
#interface DataViewCustomCell : UITableViewCell {
UIColor* cellColor;
UIColor* standardColor;
}
- (void) setCellColor: (UIColor*)color;
#end
.m
#implementation DataViewCustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void) setCellColor: (UIColor*)color
{
cellColor = color;
}
- (void) spreadBackgroundColor: (UIView*)that withColor: (UIColor*)bkColor
{
NSEnumerator *enumerator = [that.subviews objectEnumerator];
id anObject;
while (anObject = [enumerator nextObject]) {
if([anObject isKindOfClass: [UIView class]])
{
((UIView*)anObject).backgroundColor = bkColor;
[self spreadBackgroundColor:anObject withColor:bkColor];
}
}
}
- (void) layoutSubviews {
[super layoutSubviews]; // layouts the cell as UITableViewCellStyleValue2 would normally look like
if(!self.selected && NULL != cellColor)
{
[self spreadBackgroundColor:self withColor:cellColor];
}
}
- (void)dealloc
{
[super dealloc];
}
#end
When I call setCellColor with the color I want, all goes well, but when I haven't found a way to set the original color back: when I set [UIColor clearColor] with UITableViewStylePlain style the results is not good-looking.
How can I achieve a good result, without a missing cell separator line?
I was having a similar problem and found edo42's answer. However I was then having an issue with the background behind the text in the cell not displaying the background color I set. I believe this is due to the style: UITableViewCellStyleSubtitle.
In case others stumble upon this question, I believe the better solution for this is found in this question:
BackgroundColor of UITableViewCellStyleSubtitle labels?
BackgroundColor of UITableViewCellStyleSubtitle labels?
Answer reprinted here:
To change the background color of the table view cell, you'll need to set it in tableView:willDisplayCell:forRowAtIndexPath: rather than tableView:cellForRowAtIndexPath: otherwise it won't have any effect, for example:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor whiteColor];
}
Finally, I solved it by myself. I used the following code in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath instead of subclassing:
UIView *bg = [[UIView alloc] initWithFrame:cell.frame];
bg.backgroundColor = [UIColor greenColor]; //The color you want
cell.backgroundView = bg;
cell.textLabel.backgroundColor = bg.backgroundColor;
[bg release];
why don't before you set the new cell color, capture the old cell color in a UIColor variable.
try
UIColor *originalColor = anObject.backgroundColor;
then later when you want to change back to that just change the cell color to originalColor.
I find it best to adjust the color from within the custom cell's .m file, rather than the tableViewController. Seems more intuitive, and it's slightly easier. Just adjust the color as necessary in the methods:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
and
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
Note: make sure you call the super of these methods too at the end of the call, e.g. if you want to make your cell green on touch:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.backgroundColor = [UIColor greenColor];
[super touchesBegan:touches withEvent:event];
}
Also, in my experience, it's not worth adjusting the color in touchesEnded, because your cell often won't adjust in-time for quick selections by the user.
you should always provide changes for cell in willDisplayCell:forRowAtIndex instead of cellForRowAtIndex method , as per Apple Documentation
This Works !!
Change the color in the following delegate method:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (...){
cell.backgroundColor = [UIColor blueColor];
} else {
cell.backgroundColor = [UIColor whiteColor];
}
}