I have table view in side bar which is similar to facebook app. In my sidebar tableview i have imageview in each row. I want the imageview will be changed when i clicked the cell and it will be retain while for selecting another cell. 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.contentView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIView * contentView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 60)];
UIImageView * cellImg = [[UIImageView alloc]initWithFrame:CGRectMake(5,8,259, 60)];
[cellImg setImage:[UIImage imageNamed:[menuArr objectAtIndex:indexPath.row]]];
[contentView addSubview:cellImg];
[contentView setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:contentView];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
delegate.sideBarSelectedIndex = indexPath.row;
NSLog(#"delegate.sideBarSelectedIndex: %d",delegate.sideBarSelectedIndex);
[UIView commitAnimations];
if (self.sidebarDelegate) {
NSObject *object = [NSString stringWithFormat:#"ViewController%d", indexPath.row];
[self.sidebarDelegate sidebarViewController:self didSelectObject:object atIndexPath:indexPath];
[delegate.firstLensePageObj timerFunction:indexPath.row];
}
}
Try this in your didSelectRowAtIndexPath delegate method :-
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"yourImage"];
Try this in cellForRowAtIndexPath.
UIImageView *selectedImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Your Image"]];
cell.selectedBackgroundView = selectedImageView;
Need to capture the selected indexpath in didSelectRowAtIndexPath: method and need to reload the tableview in that method. In cellForRowAtIndexPath need to check the selected index with current index.
- (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.contentView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIView * contentView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 60)];
UIImageView * cellImg = [[UIImageView alloc]initWithFrame:CGRectMake(5,8,259, 60)];
if (delegate.sideBarSelectedIndex == indexpath.row){
//Selected cell
[cellImg setImage:[UIImage imageNamed:[selectedMenuArr objectAtIndex:indexPath.row]]];
}else {
//Unselected cell
[cellImg setImage:[UIImage imageNamed:[menuArr objectAtIndex:indexPath.row]]];
}
[contentView addSubview:cellImg];
[contentView setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:contentView];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
delegate.sideBarSelectedIndex = indexPath.row;
NSLog(#"delegate.sideBarSelectedIndex: %d",delegate.sideBarSelectedIndex);
[UIView commitAnimations];
if (self.sidebarDelegate) {
NSObject *object = [NSString stringWithFormat:#"ViewController%d", indexPath.row];
[self.sidebarDelegate sidebarViewController:self didSelectObject:object atIndexPath:indexPath];
[delegate.firstLensePageObj timerFunction:indexPath.row];
}
}
Related
I have delegate method that retrieves the content for each cell like this:
-(void)getRetrievedShopContentStickerName:(NSArray *)stickerNameArray price:(NSArray *)stickerPriceArray profileBackgroundImage:(NSArray *)stickerProfileBackgroundImageArray profile:(NSArray *)stickerProfileImageArray profileMenuImage:(NSArray *)stickerProfileMenuImageArray designerName:(NSArray *)designerNameArray
{
self.stickerPriceArray = [[NSMutableArray alloc] initWithArray:stickerPriceArray];
self.stickerProfileBGImageArray = [[NSMutableArray alloc] initWithArray:stickerProfileBackgroundImageArray];
NSLog(#"sticker price: %#", self.stickerPriceArray);
NSLog(#"sticker bg: %#", self.stickerProfileBGImageArray);
[self.shopTableView reloadData];
}
This delegate methods logs out a working an array as expected. This is code I used for displaying table view content:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.stickerPriceArray.count;
}
- (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];
AsyncImageView *backgroundImage = [[AsyncImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)]; //does cell frame get before this method?
[backgroundImage setTag:123];
[cell.contentView addSubview:backgroundImage];
UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
[priceLabel setTag:124];
[priceLabel setFont:[UIFont fontWithName:#"Helvetica-Light" size:30.0f]];
[priceLabel setTextColor:[UIColor blackColor]];
[cell.contentView addSubview:priceLabel];
}
[(AsyncImageView *)[cell.contentView viewWithTag:123] loadImageWithTypeFromURL:[NSURL URLWithString:[self.stickerProfileBGImageArray objectAtIndex:indexPath.row]] contentMode:UIViewContentModeScaleAspectFit imageNameBG:nil];
[(UILabel *)[cell.contentView viewWithTag:124] setText:[self.stickerPriceArray objectAtIndex:indexPath.row]];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100;
}
The only change I get after reloading the table view in the delegate method is the height of each tableviewcell. Why doesn't my contents show? What did I do wrong?
Thanks in advance
I accidentally set my cell's identifier in the storyboard so the if (cell == nil) was never called.
I am confused about how to custom a UITableViewCell highlighted style, not only the highlighted cell background color, but also the frame of its subviews(an imageview)?
The
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
method doesn't work for me. If I only change the highlighted color of the cell, it works very well. But it doesn't work for changing the frame of cell's subviews.
Thanks for any help!
You can do it by following way
below is Sample code for it
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *strIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIImageView *imgv = [[UIImageView alloc] initWithFrame:CGRectMake(278, 2, 40, 40)];
[imgv setBackgroundColor:[UIColor grayColor]];
imgv.tag = 100 + indexPath.row;
[cell.contentView addSubview:imgv];
[cell.textLabel setText:[NSString stringWithFormat:#"Cell: %d",indexPath.row]];
[cell.detailTextLabel setText:[NSString stringWithFormat:#"%03d - %03d",indexPath.section, indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.textLabel setBackgroundColor:[UIColor orangeColor]];
//set the frame of subview on highlight
UIImageView *imgv = (UIImageView*)[cell.contentView viewWithTag:100+indexPath.row];
[imgv setBackgroundColor:[UIColor orangeColor]];
[imgv setFrame:CGRectMake(238, 2, 80, 40)];
}
-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.textLabel setBackgroundColor:[UIColor clearColor]];
//now reset the frame of subview on Unhighlight
UIImageView *imgv = (UIImageView*)[cell.contentView viewWithTag:100+indexPath.row];
[imgv setBackgroundColor:[UIColor grayColor]];
[imgv setFrame:CGRectMake(278, 2, 40, 40)];
}
Best to just use the delegate protocols:
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
// and
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
Then just make the adjustments directly to your UITableViewCell via UITableViewCell *cell = [tableView cellforRowAtIndexPath:indexPath];.
I have a UITableview in this view i created uiwebview for each cell. When i tap on a cell i want the view of UIWebView. How to achieve this??
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
[[cell.contentView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
cell.accessoryType = UITableViewCellAccessoryNone;
UIView *customView = [[UIView alloc]init];
customView.transform = CGAffineTransformMakeRotation(M_PI_2);
[customView setFrame:CGRectMake(0, 0, 1024, 768)];
[customView setBackgroundColor:[UIColor clearColor]];
UIWebView *menuWeb = [[UIWebView alloc]init];
[menuWeb setFrame:CGRectMake(0, 0, 768, 1024)];
[menuWeb setDelegate:self];
[menuWeb setUserInteractionEnabled:YES];
[menuWeb.scrollView setScrollEnabled:NO];
[menuWeb setScalesPageToFit:YES];
NSURL *url = [NSURL fileURLWithPath:[urlArr objectAtIndex:indexPath.row]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[menuWeb loadRequest:request];
[customView addSubview:menuWeb];
[cell.contentView addSubview:customView];
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}
in cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
UIView *customView = [[UIView alloc]init];
customView.tag = 100;
....
return cell;
}
and in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIView *customView = [cell.contentView viewWithTag:100];
for (id view in customView.subViews) {
if ([view isKindOfClass:[UIWebView class]]) {
UIWebView *menuWeb = (UIWebView *)view;
}
}
}
hope this will help
There are a couple of ways you can achieve this.
The simplest way would be to assign a tag to the webview and then retreive it when the cell is tapped.
When you create the cell add:
[menuWeb setTag:SOME_CONSTANT_NUMBER];
Then inside the webview delegate's didSelectRowAtIndexPath method retrieve the cell and it's webView:
UITableViewCell *cell = [tableVoew cellForRowAtIndexPath:indexPath];
UIWebView *webView = [cell viewWithTag:SOME_CONSTANT_NUMBER];
Try this one, in cellForRowAtIndexPath tag CustomView and webview so that you can retrieve using tag-
......
customView.tag = 111;
......
webView.tag = 222;
.......
Then in didSelectRowAtIndexPath
UITableViewCell *cell = (UITableViewCell *) [tableView cellForRowAtIndexPath:indexPath];
UIView *customView = [cell.contentView viewWithTag:111];
Use viewWithTag to find out webview
UIWebView *wView = [customView viewWithTag:222];
Or iterate over custom view to find out webview
UIWebView *wView = nil;
for ((id) subView in [customView subviews]) {
if ([subView isKindOfClass:[UIWebView class]]){
//Found WebView
wView =(UIWebView *) subView;
break;
}
}
In my my application I want to change the cell text color with out disappearing the cell separator.And I am using the following code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *identifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView * selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
[selectedBackgroundView setBackgroundColor:[UIColor clearColor]]; // set color here
[cell setSelectedBackgroundView:selectedBackgroundView];
cell.backgroundColor=[UIColor clearColor];
cell.textLabel.highlightedTextColor = [UIColor redColor];
[cell setOpaque:NO];
}
cell.textLabel.text=[contentArray objectAtIndex:indexPath.row];
return cell;
}
But when I clicked the cell the cell separator also is disappearing ? How to change the text color without hiding the separator ?
It seems the cell separators are a problem for a lot of people. So, I would say rather than doing what I suggested to disable the selection, it would be easier to set the cell separator to 'none' and manage the separator yourself in the background and selected background views:
- (void)viewDidLoad
{
[super viewDidLoad];
// ...
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *identifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
[selectedBackgroundView setBackgroundColor:[UIColor clearColor]];
[cell setSelectedBackgroundView:selectedBackgroundView];
UIView *backgroundView = [[UIView alloc] initWithFrame:cell.frame];
[backgroundView setBackgroundColor:[UIColor clearColor]];
[cell setBackgroundView:backgroundView];
UIView *selectedBackgroundSeparator = [[UIView alloc] initWithFrame:CGRectMake(tableView.separatorInset.left, cell.frame.size.height - 1, cell.frame.size.width - tableView.separatorInset.left, 1)];
UIView *backgroundSeparator = [[UIView alloc] initWithFrame:selectedBackgroundSeparator.frame];
selectedBackgroundSeparator.backgroundColor = backgroundSeparator.backgroundColor = tableView.separatorColor;
[selectedBackgroundView addSubview:selectedBackgroundSeparator];
[backgroundView addSubview:backgroundSeparator];
cell.textLabel.highlightedTextColor = [UIColor redColor];
[cell setOpaque:NO];
}
cell.textLabel.text=[contentArray objectAtIndex:indexPath.row];
return cell;
}
Alternatively, you can use the default cell separator, and instead just add your own top and bottom separators to the selectedBackgroundView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *identifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
[selectedBackgroundView setBackgroundColor:[UIColor clearColor]];
[cell setSelectedBackgroundView:selectedBackgroundView];
UIView *topSelectedBackgroundSeparator = [[UIView alloc] initWithFrame:CGRectMake(tableView.separatorInset.left, 0, cell.frame.size.width - tableView.separatorInset.left, 1)];
UIView *selectedBackgroundSeparator = [[UIView alloc] initWithFrame:CGRectOffset(topSelectedBackgroundSeparator.frame, 0, cell.frame.size.height)];
topSelectedBackgroundSeparator.backgroundColor = selectedBackgroundSeparator.backgroundColor = tableView.separatorColor;
[selectedBackgroundView addSubview:selectedBackgroundSeparator];
[selectedBackgroundView addSubview:topSelectedBackgroundSeparator];
cell.textLabel.highlightedTextColor = [UIColor redColor];
[cell setOpaque:NO];
}
cell.textLabel.text=[contentArray objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
for(id view in cell.containtView.subview) {
if([view isKindaOfClass:[UILabel class]])
UILabel* titleLabel = (UILabel*)view;
[titleLabel setTextColor:[UIColor whiteColor]]; // any you want
}
}
Rather than setting the cell's selectedBackgroundView to a clear view, would simply not allowing the cell to be highlighted when selected accomplish what you want? It will prevent the cell and separators from changing automatically based on the selection, but you will have to manage recognizing the tap gesture and highlighting the label text yourself.
Remove the selectedBackgroundView from your code.
You then need to implement tableView:shouldHighlightRowAtIndexPath: in your UITableViewDelegate:
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO; // do what's appropriate based on the indexPath
}
I have a table view with many cells. In the first cell I placed a UIImageView to hold a pic and next to it a button that will open up a popOver.
My question is: Why is this cell is getting reused in spite of checking (cell==nil) while others are working fine.
The code is as below.
P.S. This is without using storyboard and xib only programatically.
- (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];
}
if (indexPath.section == 0)
{
if(indexPath.row==0)
{
if(self.imageView==nil)
{
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(30, 2, 50, 40)];
self.imageView.image = [UIImage imageNamed:#"user.png"];
self.imageView.backgroundColor=[UIColor blackColor];
}
[cell.contentView addSubview:self.imageView];
if(self.chooseImage==nil)
{
self.chooseImage = [[UIButton alloc]initWithFrame:CGRectMake(270, 10, 80, 30)];
[self.chooseImage addTarget:self action:#selector(chooseImage:) forControlEvents:UIControlEventTouchUpInside];
self.chooseImage.backgroundColor = [UIColor blackColor];
[self.chooseImage setTitle:#"CHOOSE" forState:UIControlStateNormal];
}
[cell.contentView addSubview:self.chooseImage];
}
First in code add at end of the method return cell; and use following 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];
if(self.imageView==nil)
{
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(30, 2, 50, 40)];
self.imageView.image = [UIImage imageNamed:#"user.png"];
self.imageView.backgroundColor=[UIColor blackColor];
}
[cell.contentView addSubview:self.imageView];
if(self.chooseImage==nil)
{
self.chooseImage = [[UIButton alloc]initWithFrame:CGRectMake(270, 10, 80, 30)];
[self.chooseImage addTarget:self action:#selector(chooseImage:) forControlEvents:UIControlEventTouchUpInside];
self.chooseImage.backgroundColor = [UIColor blackColor];
[self.chooseImage setTitle:#"CHOOSE" forState:UIControlStateNormal];
}
[cell.contentView addSubview:self.chooseImage];
}
return cell; // this line is not in your code so add this line.
}