I'm trying to change the custom accessoryView of a uitableviewcell immediately after the user clicks on the cell. How would I do this?
For the record, I'm using Matt Gallagher' custom table view tutorial:
http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html
Download link for source: http://projectswithlove.com/projects/EasyCustomTable.zip
EDIT
Tried this code, but it just changes the accessory AFTER touch-up. Also tried willSelectRowAtIndexPath with same result.
- (NSIndexPath *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *indicatorImage = [UIImage imageNamed:#"indicatorSelected.png"];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = [[[UIImageView alloc] initWithImage:indicatorImage] autorelease];
return indexPath;
}
EDIT
Problem solved by making the background image of the cell contain the accessories. so the accessory was 'faked' by making it part of the image
Perhaps you can try to reload the cell in willSelectRowAtIndexPath/didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *indicatorImage = [UIImage imageNamed:#"indicatorSelected.png"];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = [[[UIImageView alloc] initWithImage:indicatorImage] autorelease];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:NO];
}
Another recommendation:
didSelectRowAtIndexPath returns void not NSIndexPath.
You could change the accessoryView in the selection method as shown:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = newView;
}
This just grabs the current cell that was selected and then changes the accessory view of it. Your view object would go where newView is.
Use the highlightedImage property of UIImageView:
UIImageView* arrowView = [[UIImageView alloc] initWithImage:normalImage];
arrowView.highlightedImage = selectedImage;
cell.accessoryView = arrowView;
[arrowView release];
Related
I have a custom cell with imageview and label.When user selected a particular cell in the tableview I want change its image and the label font color.How can I do this ?I want to avoid that default way of cell selection(highlight cell in blue color) and use above method instead of that.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *selectedCell = (MyCustomCell *)[tableView cellForRowAtIndexPath:indexPath];
//selectedCell.textLabel.textColor = <#your color#>
//selectedCell.myImage = <#your image>
}
if you want changed selected cell backgroundColor, try to this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellId = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:[UIColor redColor]];
[cell setSelectedBackgroundView:bgColorView];
}
}
Where do I set backgroundImage of tableview cell in cellForRowAt.. And how do I do that ? This is how I did it and it kinda works, but I want to know is that right method for setting backgroundimage (cell.backgroundView) and is it right place inside if(cell==nil) or outside that "if".?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"RootViewCellIdentifier";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.png"]];
}
return cell;
}
Used to do that, but nowadays I prefer willDisplayCell:
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundColor = [UIColor redColor];
}
Documentation says
A table view sends this message to its delegate just before it uses cell to draw a row, thereby permitting the delegate to customize the cell object before it is displayed. This method gives the delegate a chance to override state-based properties set earlier by the table view, such as selection and background color. After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out.
When using cellForRowAtIndexPath, there were some weird special cases, where cell customization just didn't work fully as I wanted. No such problems with willDisplayCell.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[cell.imageview setImage:[UIImage imageNamed:#"image1.png"]];
}
return cell;
}
try with this might be helpful...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"RootViewCellIdentifier";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
UIImageView *backimg = [[UIImageView alloc] init];
backimg.frame = CGRectMake(0, 0, 320, 44);
backimg.tag = 20;
[cell.contentView addSubview:backimg];
}
UIImageView *imag = (UIImageView *)[cell.contentView viewWithTag:20];
[imag setImage:[UIImage imageNamed:#"sky.png"]];
return cell;
}
The best place to set a background view for a cell is the tableView:willDisplayCell:forRowAtIndexPath: method.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.png"]];
}
I have created one uiviewcontroller with xib to adding in the uitableview cell. here is the code for that.
#interface CustomeCellHome : UIViewController{
IBOutlet UIImageView *imgViewBack;
// will have number of labels and imageviews.
}
#property (nonatomic, retain) UIImageView *imgViewBack;
#implementation CustomeCellHome
#synthesize imgViewBack;
all this IBOutlet connected to xib.
now i am adding this to my uitableview cell. here is code for that.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 150;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// }
CustomeCellHome *objCell = [[CustomeCellHome alloc] init];
[objCell.view setTag:indexPath.row];
[cell.contentView addSubview:objCell.view];
objCell.imgViewBack.image = [UIImage imageNamed:#"unsel.png"];
[objCell release];
return cell;
}
now i want to change this imgViewBack image on selection of row. here is code for that.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CustomeCellHome *objCCell = [[CustomeCellHome alloc] init];
objCCell.view = [cell viewWithTag:indexPath.row];
objCCell.imgViewBack.image = [UIImage imageNamed:#"sel.png"];
}
but my imgViewBack is not changing its image. don't getting what is wrong with this. any suggestion for that ? any suggestion will be appreciated .
If you must use a viewController like u do (again probably this is not what u need), I can see few problems with your code.
1) Instead of [objCell.view setTag:indexPath.row]; use [objCell.view setTag:indexPath.row+1]; otherwise u will have a problem when indexPath.row=0 (I think 0 is also the tag of the superview).
2) Don't release the viewController, if u need one keep it around.
(but u will need to save it in some data structure so later u can release it...)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = nil;
// u will have problems reusing those cells...
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if(cell == nil)
// {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CustomeCellHome *objCell = [[CustomeCellHome alloc] init];
[objCell.view setTag:indexPath.row+1];
[cell.contentView addSubview:objCell.view];
objCell.imgViewBack.image = [UIImage imageNamed:#"image1.png"];
//[objCell release]; // don't release now, add it to some data structure so u can release later
// }
return cell;
}
2) Then in didSelectRowAtIndexPath retrieve the cell's viewController and change his imgViewBack property.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// get the cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// get the cell's viewController
UIView *aView = [cell.contentView viewWithTag:indexPath.row+1];
CustomeCellHome *objCCell = (CustomeCellHome *)[aView nextResponder];
// update the image
objCCell.imgViewBack.image = [UIImage imageNamed:#"image2.png"];
}
This will change the image, but this is not a perfect solution, u will have problems if u r reusing cells... Try rethink if u really need to use the viewController.
I have a working table view on my iphone app, and am implementing a second view using navigationController.
But when I try to select a cell on the initial view, it does not respond i.e. no highlighting in blue, no selection.
Can anyone suggest what I might have missed, or what is responsible for actually selecting the cell when the user taps it?
OK thanks for your suggestions - still no luck. here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];
[cell setSelectionStyle: UITableViewCellSelectionStyleBlue];
UIView *selectionView = [[[UIView alloc] init] autorelease];
selectionView.backgroundColor =[UIColor redColor];
cell.selectedBackgroundView = selectionView;
}
// format text
cell.textLabel.font = [UIFont fontWithName:#"Arial" size:12];
cell.textLabel.text = [tableArray objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//NSUInteger row = indexPath.row;
//[DetailView selectRowAtIndexPath:indexPath animated:YES];
//UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath.row];
//[cell setSelectionStyle: UITableViewCellSelectionStyleBlue];
DetailView *detailView = [[DetailView alloc] initWithNibName:#"DetailView" bundle:nil];
[self.navigationController pushViewController:detailView animated:YES];
[DetailView release];
}
May be you have done this line of code in cellForRowatIndexPath::
cell.selectionStyle = UITableViewCellSelectionStyleNone;
If yes, then replace it with either of these:
cell.selectionStyle = UITableViewCellSelectionStyleGray;
or
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
Without looking at your code I would say you have to add this line in your cellForRowAtIndexPath delegate method.
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
And also you have to implement this delegate method which gets called when you tap on cell of UITableView..
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
In my UITableView, i need to get the event of the user, so when the cell is selected(checked), i put btn_checked.png and when it's unchecked, i put the btn_unchecked.png.
I guess, what i try to do should be in the didSelectRowAtIndexPath method, so this is my code:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *listData =[self->tableContents objectForKey:
[self->sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell* theCell = [tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"btn_unchecked.png"]];
theCell.accessoryView = imageView;
}
My snippet code doesn't work, so the btw_unchecked.png isn't placed when the row is checked, also, i need to get the event of checked/unchecked to place the right image to the right event.
Thanx in advance.
As an example, this code snippet will toggle the cell's checkmark when the cell is tapped. The pattern is to force a selective reload from the table's datasource when the delegate method is invoked.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Dequeue the cell... then:
static NSString *CellIdentifier = #"tvcOEList";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.accessoryType = (cell.accessoryType == UITableViewCellAccessoryNone) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
You can use following code.
[cell.contentView addSubview:imageView];
i hope this will help you..