How to identify each button in table row? - iphone

I want buttons in table row to show different titles depending on database values.
But I am facing issue in uniquely identifying each buttons i.e button 0, button 1 etc.
Note, button is in table row.

Have a look at this thread how-to-select-particular-check-box-in-tableview-which-is-inserted-in-table-cell

To uniquely identify the buttons in TAbleView you need to set the tag of each & every button
like
This this out,this will definitely solve your problem :)
- (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] autorelease];
}
UIButton *CameraBreak=[[UIButton alloc]init];
CameraBreak.frame=CGRectMake(28, 33, 60, 40);
CameraBreak.tag=indexPath.row;
[CameraBreak setImage:[UIImage imageNamed:#"Camera.png"] forState:UIControlStateNormal];
[CameraBreak addTarget:self action:#selector(CameraBtn_Clicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:CameraBreak];
//[CameraBreak release];
return cell;
}
-(IBAction)CameraBtn_Clicked:(id)sender
{
NSLog(#"%d",[sender tag]); /This will print the tag of button which you have pressed in TableView
}
Either for Dynamic Records use the Following link :
How to Select particular check Box in tableView which is inserted in table cell interface builder in iphone
Now that will work

use the NSObject property "tag" ... e.g.
UIButton* myButton;
myButton.tag = EON; OR myButton.tag = EOFF ;
if(myButton.tag == EON)
{
myButton.tag = EOFF;
//Do As per your requirement
}
else if(myButton.tag == EOFF)
{
myButton.tag = EON;
//Do As per your requirement
}

You can use table indexpath.row + your own values (0,1,2...) as tag to each button.
I m not sure but atleast you can try.

Related

When we scroll custom table then cell content change in iPhone

hello friends I have created custom table and add all needed delegate and datasource for table then this is working good but when we scroll my table then content change like this is code...
Table_worklist=[[UITableView alloc]initWithFrame:CGRectMake(10,480,750,130)style:UITableViewStylePlain];
Table_worklist.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
Table_worklist.delegate=self;
Table_worklist.dataSource=self;
Table_worklist.layer.borderWidth = 2.0;
Table_worklist.layer.borderColor = [UIColor grayColor].CGColor;
[ScrollView addSubview:Table_worklist];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell== nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UITextField *resultval=[[UITextField alloc]initWithFrame:CGRectMake(510,10,120,30)];
resultval.tag=1;
resultval.font = [UIFont boldSystemFontOfSize:12.0];
//the horizontal alignment of the text
resultval.textAlignment = NSTextAlignmentCenter;
resultval.contentVerticalAlignment = UIControlContentHorizontalAlignmentCenter;
resultval.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
resultval.delegate =self;
if([[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Numerical"])
{
imageLayer = field.layer;
[imageLayer setCornerRadius:02];
[imageLayer setBorderWidth:1];
imageLayer.borderColor=[[UIColor lightGrayColor]CGColor];
}
else if([[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Words"]||[[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Comment"])
{
imageLayer = field.layer;
[imageLayer setCornerRadius:06];
[imageLayer setBorderWidth:1];
imageLayer.borderColor=[[UIColor blackColor]CGColor];
UIButton *CheckMark=[[UIButton alloc]initWithFrame:CGRectMake(540,10,30,30)];
CheckMark.tag=1;
[CheckMark setImage:[UIImage imageNamed:#"DownTriangle1"]forState:UIControlStateNormal];
imageLayer = CheckMark.layer;
[imageLayer setCornerRadius:02];
[imageLayer setBorderWidth:1];
imageLayer.borderColor=[[UIColor blackColor] CGColor];
[cell.contentView addSubview:CheckMark];
}
[cell.contentView addSubview:resultval];
}
return cell;
}
this show right data for first 3or4 cell(because table height 130 so show only 3 cell at a time )for these 3 cell my table show right data ...for example
if([[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Numerical"])
{ }
then data is numerical go this if condition other wise go else condition......
but when we have for more cell like as 7-8 cell then when we scroll these cell so what happened suppose at cell-4 my controller go else if condition forComment and word data .........so at last cell -8 got numerical data so controller go in if condition but check mark button which was created in if else condition which show on my if condition data ......so i don't know what happened
when we scroll how to change my condition ......
Actually i thing when last created else if condition (which create uibutton checkmark)on cell-4 which are apply on cell-8...........but controller go in right place in if condition at cell-8 .....but last time created checkmark button generated on cell-8 ......
how to solve this problem....
Before You follow my Answer i want to tell you that following code is bad for memory management because it will create new cell for each rows of UITableView, so be careful for it.
But it is better to use, When UITableView Have Limited rows (about 50-100 may be ) then following code is helpful in your case, use it if is it suitable for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/// Put your code here
}
return cell;
}
If you have limited rows then this is best code for you.

iphone development: changing the button image on tableviewcell

In my app I am facing with a really weird problem. I am trying to solve it for hours but could not find what is the problem so far.
Well, I have a tableview with custom cells. and each cell I have a button. It is is like an empty box. When the button pressed, I want to change the related cell image of that button. Actually I successfully do that but somehow, some other cell's button images are also changing and I could not figure out why. Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//create new cell
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[cell.tickButton setTag:indexPath.row];
[cell.tickButton addTarget:self action:#selector(buttonWasPressed:)forControlEvents:UIControlEventTouchUpInside];
//cell has 2 label so I filled them with the contents of my object array that part is working with no problem
cell.leftLabel.text = [NSString stringWithFormat:#"%#", [[contacts objectAtIndex:indexPath.row]name]];
cell.rightLabel.text = [NSString stringWithFormat:#"%#", [[contacts objectAtIndex:indexPath.row]email]];
return cell;
}
in my buttonWasPressed method I simply do:
-(IBAction)buttonWasPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateNormal];
}
As I said before it works but also changes some other buttons images and also when I scroll down and get back to the initial position I see that some button images are changed.
You can access that cell and can change the button image as :
-(IBAction)buttonWasPressed:(id)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:your_row inSection:your_section];
UITableViewCell *currentCell = [table cellForRowAtIndexPath:indexPath];
UIButton *button = (UIButton *)[currentCell viewWithTag:(UIButton *)sender.tag];
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateNormal];
}
Hope it helps you.
You can deal with touch within CustomCell class. Just move method -(IBAction)buttonWasPressed:(id)sender within your custom class and add
tickButton addTarget:selfaction:#selector(buttonWasPressed:)forControlEvents:UIControlEventTouchUpInside in init method.
The problem is calling
[cell.tickButton addTarget:self action:#selector(buttonWasPressed:)forControlEvents:UIControlEventTouchUpInside];
method.
You add target everytime when your cells are reused and remove never. So your buttons have many targets and action method get called multiple times respectively. It may cause a memory leak.
Just put the addTarget method in if clause.
It will solve your one problem, which is your method get called multiple times. But when the cell is reused the button has the changed image. You need to set it back.
The best way to do that, you add a property to the contact object which are preseted in cells and set a value when the action method is fired. Then in cellForRowAtIndexPath: method you can set the image of the button by checking that property.
Do this
NSString *CellIdentifier = [NSString stringWithFormat:#"cell%d",indexPath.row];
While you set the default image to button also do this
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateSelected];
In your button action method do this:
-(IBAction)buttonWasPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
if(button.selected==NO) {
[button setSelected:YES];
}
}
Hope this helps.
To reuse your cell, you have to make it clean after dequeueing. In this case, you should reset your image first:
[cell.tickButton setImage:nil forState:UIControlStateNormal];
Before assigning anything to your cell.
You must save button's tag which was pressed than try this
if(pressed[cell.tickButton.tag])
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateNormal];
else
[cell.tickButton setImage:nil forState:UIControlStateNormal];
I guess you are giving the default image to your button inside the CustomCell class. This problem is very common in UITableviews.
All you need to do is keep track of the cells for which the button has been pressed. Do all this inside the cellForRowAtIndexPath method.
For example:
update the code inside cellForRowAtIndexPath method
if (cell == nil)
{
//create new cell
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(yourCondition==YES){
change the button image to the special image.
}
else{
keep the button image as default image.
}
return cell;
To keep track of the cells you can store the index path of the cells(whose button has been tapped) in an array. Inside cellForRowAtIndexPath check if the current indexPath is present inside your array or not

Getting a button press from a custom UITableViewCell's button

I have a project with a custom UITableViewCell (cell.h/.m/.xib) that has 2 labels (labelMain/labelSub), and 2 buttons on it (buttonName/buttonInfo) linked to 2 actions (showName/showInfo).
What I want to do is be able to access the 2 actions in my projects main viewcontroller so that when showName is pressed, a textfield.text in the viewcontroller (not in the cell) is set to that specific cell's labelMain.text.
Hope that makes sense. My problem is that if I write the action (showName) in the cell.m, I cannot access the textfield from my main viewcontroller. On the flip side, if I write the action in my viewcontroller, how do I know which button inside which cell was tapped?
Hope this makes sense...
Use tag can identify which button in which cell is being tapped.
- (UITableViewCell *)tableView:(UITableView *)tableViews cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//init identifier
if (cell ==nil)
{
//load nib file
}
buttonName.tag = indexPath.row;
[buttonName addTarget:self action:#selector(showName:) forControlEvents:UIControlEventTouchUpInside];
buttonInfo.tag = indexPath.row;
[buttonInfo addTarget:self action:#selector(showInfo:) forControlEvents:UIControlEventTouchUpInside];
}
}
-(void) showName:(UIButton*)button{
int row = button.tag; //you know that which row button is tapped
}
-(void)showInfo:(UIButton*)button{
int row = button.tag;//you know that which row button is tapped
}
---------------- EDIT -------------
If you need to know which button is pressed based on row & section, you may try this below. (in cellForRowAtIndexPath: method)
int tag = (indexPath.row+1)+(indexPath.section*100);
buttonName.tag = tag;
When button at
row = 5, section = 0 then tag = 6.
row = 4, section = 3 then tag = 305.
row = 0, section = 11 then tag =1101.
limitation, row cannot be more than 99. and DON'T use positive tag for other view. if you need use tag, try negative. (-1, -9, -100).
so from here, you can calculate back row & section of indexPath. using this :
-(NSIndexPath*)getIndexPathFromTag:(NSInteger)tag{
/* To get indexPath from textfeidl tag,
TextField tag set = (indexPath.row +1) + (indexPath.section*100) */
int row =0;
int section =0;
for (int i =100; i<tag; i=i+100) {
section++;
}
row = tag - (section*100);
row-=1;
return [NSIndexPath indexPathForRow:row inSection:section];
}
how to use :
-(void)showInfo:(UIButton*)button{
NSIndexPath *indexPath = [self getIndexPathFromTag:button.tag];
int row = indexPath.row;
int section = indexPath.section;
}
Try this in viewController.m file in cellForRowAtIndexPath method
[[customCell showNameBtn] setTag:indexPath.row];
[[customCell showNameBtn] addTarget:self action:#selector(showName:) forControlEvents:UIControlEventTouchDown];
-(void) showName:(id)sender
{
// check here the sender tag and then perform you action what you want.
}
I suggest to use delegate(protocol) method for this. You will be having full control on the button, cell and the view controller. And its very simple too
The simplest solution in my opinion:
In your CustomCell.h :
#property (nonatomic, copy) void (^buttonTapAction)(id sender);
In your CustomCell.m create the IBAction and connect it to your UIButton :
-(IBAction)cellButtonIsPressed:(id)sender{
if (self.buttonTapAction) {
self.buttonTapAction(sender);
}
}
Then in the ViewController.m where your UITableView is managed :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* cellIdentifier = #"customCell";
CustomCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.buttonTapAction = ^(id sender){
//Do what you want to do when the button inside THIS cell is clicked
};
}
Try to create the button dynamically, with its methods in same controller. Do this in cellForRowAtIndexPath: method:
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"WorkRequestedCC" owner:self options:nil];
{
for (id oneObject in nib) if ([oneObject isKindOfClass:[WorkRequestedCC class]])
cell = (WorkRequestedCC *)oneObject;
}
UILabel *costLbl=[[UILabel alloc]initWithFrame:CGRectMake(792, 13, 10, 15)];
costLbl.text=#"$";
[costLbl setBackgroundColor:[UIColor clearColor]];
UITextField *txtCost=[[UITextField alloc]initWithFrame:CGRectMake(805, 10, 94, 27)];
txtCost.backgroundColor=[UIColor whiteColor];
[txtCost setKeyboardType:UIKeyboardTypeNumberPad];
txtCost.text=obj.expCost;
[txtCost addTarget:self action:#selector(textChanged:) forControlEvents:UIControlEventEditingChanged];
[cell.contentView addSubview:costLbl];
[cell.contentView addSubview:txtCost];
cell.lblDes.text=obj.expDes;
}
- (void)textChanged
{
//your code here
}

problem with check mark in iphone

I am new to the iPhone. I'm creating an application. For that I want to send friends an invitation from my app to a Facebook profile. My Facebook friends are listed in a TableView.
I want to select 40 fiends at a time and send invitation to friends' wall.
In my app I wrote to display my friends:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Displayfriendscell";
Displayfriendscell *cell = (Displayfriendscell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[Displayfriendscell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure the cell...
NSString *name=[Friendsarray objectAtIndex:indexPath.row];
//NSLog(#"name is%#",friendid);
cell.nameLabel.text = name;
return cell;
}
What should I do for that? I have no idea about check marks and their workings. I just want an idea about it. Can anybody help me implement this?
Basically, cells have an accessoryType for checkmark you can use:
Unselected cells start off as no accessory type:
cell.accessoryType = UITableViewCellAccessoryNone;
When a cell is selected:
cell.accessoryType = UITableViewCellAccessoryCheckmark;
Also, somewhere you'll need to keep track of which items in your datasource (I.e. Friendsarray) have been selected, since the UITableView will reuse it's cells. For example another array filled with NSNumbers - 0 for unselected and 1 for selected (another example would be to change Friendsarray to a 2 dimensional array. Or, since your integrating with facebook, it probably would be best in the long run to create a class of 'friend' and make an array of that, where one of the fields is 'selected').
Since UITableView reuses cells as you scroll the table, your cellForRowAtIndexPath will need to check with your array to see if the cell should be set to checked or unchecked.
The code for selecting the cell goes in:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
When the user completes you'll loop through your datasource (your array or whatever) and get the selected friends.
Hope that's the guidance you're looking for.
What you want to implement is multiple row selection. Look at these links
Is it possible to configure a UITableView to allow multiple-selection?
Select multiple rows in UITableview
This might help you:
in your cellForRowAtIndexPath method do like this:
NSString *name=[Friendsarray objectAtIndex:indexPath.row];
UILabel *lblName = [[UILabel alloc]initWithFrame:CGRectMake(10, 8, 250, 20)];
lblName.text = name;
[cell addSubview:lblName];
UIButton *btnCheck = [UIButton buttonWithType:UIButtonTypeCustom];
btnCheck.frame = CGRectMake(290, 8, 16, 16);
[btnCheck setImage:[UIImage imageNamed:#"checkbox.png"] forState:UIControlStateNormal];
[btnCheck setTitle:#"0" forState:UIControlStateNormal];
[btnCheck addTarget:self action:#selector(btnClicked:)forControlEvents:UIControlEventTouchUpInside];
btnCheck.tag = indexPath.row+1;
[cell addSubview:btnCheck];
// in selector method (btnClicked):
-(void)btnClicked:(id)sender
{
UIButton *btnTemp = (UIButton*)sender;
UIButton *btnSelected = (UIButton*) [self.view viewWithTag:btnTemp.tag];
NSString *strTitle = btnSelected.titleLabel.text;
if([strTitle isEqualToString:#"0"])
{
[btnSelected setTitle:#"1" forState:UIControlStateNormal];
[btnSelected setImage:[UIImage imageNamed:#"checkbox-checked.png"] forState:UIControlStateNormal];
}
else
{
[btnSelected setTitle:#"0" forState:UIControlStateNormal];
[btnSelected setImage:[UIImage imageNamed:#"checkbox.png"] forState:UIControlStateNormal];
}
}
// use two image, one is small sqaure and another with tickmarked image

Button placement on table footer view

I have a table view wherein the number cells are not fixed and will keep on changing. I have to show two action buttons after my last cell in the table footer. How can I place them properly after my last cell? I know the pixel spacing between last cell and these buttons. Any code sample will be really helpful.
Have you tried sticking them in a view and setting that as the footer view?
You need to give it the correct height before you add it; the width is automatically set to the width of the table. Either set it to a sensible width (e.g. 320) and use autoresizing or use a custom UIView subclass and implement -layoutSubviews.
You could always add two buttons to the final cell.
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
return [myCellDataArray count]+1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
if (indexPath.row > [myCellDataArray count]) {
cell = [tableView dequeueReusableCellWithIdentifier:#"Button Cell"];
if (cell == nil) {
UIButton *firstButton = [[UIButton alloc] init];
//customization
UIButton *secondButton = [[UIButton alloc] init];
//customization
[cell addSubView:firstButton];
[cell addSubView:firstButton];
}
} else {
// normal stuff
}
If you want to customize existing buttons you need to set it's tag to something unique, i.e. firstButton.tag = 100 and then set firstButton by firstButton = (UIButton *)[cell viewWithTag:100];. Make sure you define firstButton so that it's in scope!
Hope this helps!