I have a button in each cell in my tableview. Basically I'm saving the cell's indexPath in the button's tag in thecellForRowAtIndexPath` method like this:
- (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];
}
UIButton *expandPhoto = (UIButton *)[cell viewWithTag:101];
expandPhoto.tag = indexPath.row;
[expandPhoto addTarget:self action:#selector(expand:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
The problem is, when i scroll down the button's indexPath resets.
I've searched alot in the internet but I'm stuck with this problem for days.
You are using static NSString *CellIdentifier = #"Cell"; it will reuse the cells so you will get the cell index as 0 when it should show 6, shows 1 when it should show 7, etc..
If you want to get the index as 0,1,....6,7, etc..
Use Like this,
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d",indexPath.row];
But it wont reuse the cell.
I solved my issue using this 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];
}
UIButton *expandPhoto = (UIButton *)[cell viewWithTag:101];
[expandPhoto setTag:indexPath.row];
[expandPhoto addTarget:self action:#selector(expand:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (IBAction)expand:(id)sender {
UIButton *btn = (UIButton*) sender;
UITableViewCell *cell = (UITableViewCell*) btn.superview.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
int row = indexPath.row;
}
Thanks.
Custom table view cell is the best approuch to solve this problem here we need to create different the Custom table view cell controller and use this in cellForAtIndexPath tableview Datasource :
CustomTableViewCell.h
#import <UIKit/UIKit.h>
#interface CustomTableViewCell : UITableViewCell
#property (nonatomic, readonly) UILabel *tblViewLabel;
#property (nonatomic, readonly) UIButton *tblViewBtn;
#end
CustomTableViewCell.m
#import "CustomTableViewCell.h"
#implementation CustomTableViewCell
#synthesize tblViewLabel = _tblViewLabel;
#synthesize tblViewBtn = _tblViewBtn;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString
*)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
_tblViewLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 8, 50, 30)];
[self.contentView addSubview:_tblViewLabel];
[_tblViewLabel release];
_tblViewBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
_tblViewBtn.frame = CGRectMake(100, 5, 200, 20);
[_tblViewBtn.titleLabel setText:[NSString stringWithFormat:#"%d",self.tag]];
[_tblViewBtn addTarget:self action:#selector(tblBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:_tblViewBtn];
[_tblViewBtn release];
}
return self;
}
- (void)tblBtnPressed :(UIButton *)btn {
NSLog(#"Here %d button is pressed.",btn.tag);
}
- (void)dealloc {
[_tblViewLabel release];
[_tblViewBtn release];
[super dealloc];
}
#end
//------------------------//
Here In Your Previous controller's cellForRowAtIndexPath datasource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *MyIdentifier = #"MyIdentifier";
CustomTableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:MyIdentifier] ;
if (cell == nil){
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
cell.tblViewLabel.text =[NSString stringWithFormat:#"%d",indexPath.row];
[cell.tblViewBtn setTitle:[NSString stringWithFormat:#"%d",indexPath.row] forState:UIControlStateNormal];
cell.tblViewBtn.tag = indexPath.row;
return cell;
}
Related
Can you please help me to do this one?
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [popOveritem objectAtIndex:indexPath.row];
[cell.textLabel setFont:[UIFont systemFontOfSize:10.05f]];
cell.imageView.image = [UIImage imageNamed:[popimage objectAtIndex:indexPath.row]];
NSLog(#"cellCOntent%#",cell.textLabel.text);
UIView *cellbgColorView = [[[UIView alloc] init]autorelease];
[cellbgColorView setBackgroundColor:[UIColor colorWithRed:40/255.0 green:128/255.0 blue:184/255.0 alpha:1.0]];
cell.selectedBackgroundView = cellbgColorView;
tableVIEW.scrollEnabled = NO;
return cell;
first time the tableview will show one record and when i click to the button appeared in the view will add another row at the top of the table view?
take a look at the below code hope it gives you what you need
viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIAlertViewDelegate,UITableViewDataSource,UITableViewDelegate>
{
IBOutlet UITableView *tblTest;
NSMutableArray *arrData;
int increment;
}
-(IBAction)onClickAdd:(id)sender;
#end
viewcontroller.m
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrData = [[NSMutableArray alloc] initWithObjects:#"Data 1", nil];
increment = 1;
}
-(IBAction)onClickAdd:(id)sender
{
increment++;
NSString *strInsertData = [NSString stringWithFormat:#"Data %d",increment];
[arrData insertObject:strInsertData atIndex:0];
[tblTest reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [arrData 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:nil];
cell.accessoryView = nil;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
cell.textLabel.text = [arrData objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I need to pass an string value from UItable View Controller to Uitable view cell
Here is the code which i used
In my Table view controller
#import <UIKit/UIKit.h>
#import "CustomCell.h"
#interface DetViewController : UITableViewController
{
NSString *urlstring;
CustomCell *cust;
}
#property(nonatomic,retain)NSString *urlstring;
#property(nonatomic,retain)NSMutableArray *mutarray;
#property(nonatomic,retain)CustomCell *cust;
#end
and im TableViewController.m have
- (void)viewDidLoad
{
[super viewDidLoad];
url=[NSURL URLWithString:urlstring];
urldata=[[NSString alloc]initWithContentsOfURL:url];
mutarray=[[NSMutableArray alloc]init];
self.mutarray=[urldata JSONValue];
NSDictionary *dict=[mutarray objectAtIndex:0];
self.title=[dict valueForKey:#"category"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell =(CustomCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.custurlstring=urlstring;
NSLog(#"%#", cell.custurlstring);
return cell;
}
In my Custom Tableviewcell.h have
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell{
NSString *custurlstring;
}
#end
My custom Tableviewcell.m have
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
NSLog(#"%#",custurlstring);
}
return self;
}
Now i got the string content in tableviewcontroller by using NSLog..but if i tried to print the value in TableViewCell i cant get those values...
Guidance Please...
No need of customizing a cell for displaying a image and labels on it,
Just add them in normal cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:<style enum value> reuseIdentifier:reuseIdentifier string:urlstring]
//cell.mystring = self.mystring;
}
// customize your image and your labels here with rects here
UIImageView *image = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"yourimage.png"]];
[cell.contentView addSubview:image];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(your rect here)];
[cell.contentView addSubview:label];
return cell;
}
You need to setup your cell in cellForRowAtIndexPath: and then set the string on the cell inside this method. This method is already provided to you when you create a UITableViewController.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.custurlstring = urlstring;
return cell;
}
You should do it in delegate method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can write something like that:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:<style enum value> reuseIdentifier:reuseIdentifier string:urlstring]
//cell.mystring = self.mystring;
}
return cell;
}
Added:
You can write custom constructor and initialize the cell using it. This way NSLog will print the string as expected:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier string:(NSString *)string
{
self = [self initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.custurl=[NSURL URLWithString:string];
NSLog(#"%#",custurl);
}
return self;
}
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 want to implement UITableView Where I want to have 3 buttons in each UITableViewCell, I want to assign Tittles to each buttons Dynamically, if am having all titles in 'title_array
' say then how can I get the index to an array for giving tittles to each buttons in each UITableViewCell ?
here is my code ,
which is not working,
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// printf("\ncellForRowAtIndexPath\n");
//static NSString *CellIdentifier = #"Cell";
NSString *CellIdentifier = [NSString stringWithFormat:#"identifier_%d", indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
//cell.textLabel.text=#"Golbal VC";
int x=50;
if (indexPath.row == 0) {
sample = 0;
}else{
if (sample == [titles_array count]-1);
else sample += 2;
}
for(int i =0; i <2 ; i++){
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(x,50,300, 300)];
[btn setBackgroundImage:[UIImage imageNamed:#"Canada.gif"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:btn];
UILabel *tit_lbl=[[UILabel alloc]initWithFrame:CGRectMake(10,10,280,45)];
[tit_lbl setText:[titles_array objectAtIndex:sample]];
[btn addSubview:tit_lbl];
[tit_lbl release];
UILabel *src_lbl=[[UILabel alloc]initWithFrame:CGRectMake(10,65,280,25)];
[src_lbl setText:[source_array objectAtIndex:sample]];
[btn addSubview:src_lbl];
[src_lbl release];
x=x+350;
/*if(index == [titles_array count]-1)
break;
index++;
*/
}
return cell;
}
You should have to try using this link and create custom cell accordingly and put three buttons in your UITableViewCell XIB file... This is the simplest method for doing this... and assign tag to each button in XIB...
http://blog.webscale.co.in/?p=284
http://www.e-string.com/content/custom-uitableviewcells-interface-builder
http://adeem.me/blog/2009/05/30/iphone-sdk-tutorial-part-6-creating-custom-uitableviewcell-using-interface-builder-uitableview/
you should use titleArray with NSDictionary objects, where you can provide title to your buttons according to the position in the cell( jus for example, you can use anything to identify your buttons).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dict = (NSDictionary*)[titleArray objectAtIndex:indexPath.row];
UILabel *tit_lbl=[[UILabel alloc]initWithFrame:CGRectMake(10,10,280,45)];
[tit_lbl setText:[dict valueForKey:#"titleLabel"]];
[btn addSubview:tit_lbl];
[tit_lbl release];
UILabel *src_lbl=[[UILabel alloc]initWithFrame:CGRectMake(10,65,280,25)];
[src_lbl setText:[dict valueForKey:#"sourceLabel"]];
[btn addSubview:src_lbl];
[src_lbl release];
return cell;
}
Hope it helps..
I have a tableViewController, the cells contains a button and a label. I need to get the text of the cell (actually the object of the cell Person) when the user clicks on the button.
When the user clicks on the button the following method gets executed;
-(void) buttonOfCellClicked{
// here i need to access the `Person` object that the user clicked
}
How do i write this code?
EDIT:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Person *person = [personsArr objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] ;
label = [[UILabel alloc]initWithFrame:CGRectMake(15, 5, 75, 60)];
label.text =person.firstName;
[cell addSubview:label];
UIButton *button= [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(buttonOfCellClicked) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
}
id findAncestor(UIView *view, Class class) {
while (view && ![view isKindOfClass:class])
view = [view superview];
return view;
}
- (void)buttonOfCellClicked:(UIButton *)button
{
UITableViewCell *cell = (UITableViewCell *)findAncestor(button, [UITableViewCell class]);
UITableView *table = (UITableView *)findAncestor(cell, [UITableView class]);
NSIndexPath *path = [table indexPathForCell:cell];
if (!path)
return;
Person *person = [personsArr objectAtIndex:path.row];
// do whatever with person
}
I would subclass UITableviewCell and add a property and the action to that class and in IB connect the button. When you are configuring the cell just set the person object. This approach would depend heavily on what you plan on doing with that object.
You need to ask your button to tell you where it is. To achieve this, you need to call superview twice (1x will return cell.contentView, 2x will return cell):
- (void)buttonOfCellClicked:(UIButton *)sender {
UITabvleViewCell *cell = (UITableViewCell *)[[sender superview] superview];
}
Then you can access cell's properties e.g. cell.textLabel.text
EDIT: You also need to add : to your -addTarget:action:forControlEvents: in cellForRow after buttonOfCellClicked text:
[button addTarget:self action:#selector(buttonOfCellClicked:) forControlEvents:UIControlEventTouchUpInside]
EDIT2: you can access person by
NSIndexPath *ip = [yourTableView indexPathForCell:cell];
Person *p = [personArr objectAtIndex:ip.row];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [yourArray count];\
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] ;
UIButton *button= [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTag:indexPath.row]; // SET TAG TO YOUR BUTTON, IT WILL BE SAME AS YOUR OBJECT AT INDEX OF ARRAY
[button addTarget:self action:#selector(buttonOfCellClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
}
-(void) buttonOfCellClicked:(id) sender{
Person *person = [yourArray objectAtIndex:[sender tag]];
// here i need to access the `Person` object that the user clicked
}