Getting a button press from a custom UITableViewCell's button - iphone

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
}

Related

Unhighlight row returns a max int on indexpath when user scrolls table with a cell highlighted

I have a UILabel as subview of my cell. When user highlight a cell the label text change it's color and when the cell is unhighlighted the color changes back, just like an usual cell textLabel.
The problem is that if the user tap a cell and scroll the table the cell will unhighlight, the unhighlight delegate method will be called but it will return [2147483647, 2147483647] as index path and the text will not change, as there is no cell on that index path.
Here is the code:
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath*)indexPath{
NSInteger section = [indexPath section];
//only change the text on cells at section 1
if (section == 1) {
//get cell with given index path
UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:indexPath];
// retrieve the UILabel by it's tag
UILabel *cellLabel = (UILabel *)[currentCell viewWithTag:1011];
cellLabel.textColor = [UIColor darkGrayColor];
}
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath*)indexPath{
NSInteger section = [indexPath section];
if (section == 1) {
UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *cellLabel = (UILabel *)[currentCell viewWithTag:1011];
[cellLabel performSelector:#selector(setTextColor:) withObject:[UIColor lightGrayColor] afterDelay:0.2f];
}
}
How can i retrieve the correct cell to change it's UILabel subview text when the user scrolls table with a cell highlighted?
Testing those methods I had the same strange results for the indexPath (no idea, why these methods are not working properly).
But I would suggest to just write your own UITableViewCell subclass and override the following method (that is called every time a cell gets selected/deselected):
- (void) setSelected : (BOOL) selected animated : (BOOL) animated {
[super setSelected: selected animated: animated];
// your customisations to your UILabel
if (selected == NO) {
self.textLabel.textColor = [UIColor lightGrayColor];
}
}
Hope this answer helps you out with your problem

Setting button tag with variable

I have a json array with certain objects : first name , last name, unique id. I am able to parse them and save them in dictionary and also check them for NULL conditions.
I have created a table in which i am able to display the names. Also, i have one button in each row as well and i have tagged them. What i want is that when i click the button, i am able to see the unique id fetched from server in my console. I need to pass this unique id to next view as using this unique id would help me to display view corresponding to that id on server.
Click here to see what I have done so far
I have made some changes by adding this to my viewDidLoad method:
for(NSDictionary *items in infos)
{
....
....
for(int i =0; i < len; i++)
{
...
...
...
for(NSDictionary *newItems in infoArray)
{
...
...
NSString *folks_IdRcv = [[items objectForKey:strr]objectForKey:#"folks_id"];
NSLog(#"FolksID = %#", folks_IdRcv);
NSString *folksIDString = [NSString stringWithFormat:#"%#", folks_IdRcv, nil];
NSLog(#"folkid_display=%#", folksIDString);
if((fName && lName && email_Id && number_id) && displayName && folksIDString != NULL)
{
...
...
[folksIDArray insertObject:folksIDString atIndex:ii];
NSLog(#"FolksID String Name = %#", [folksIDArray objectAtIndex:(ii)]);
ii++;
}
}
}
}
NSMutableArray *nArray = [[NSMutableArray alloc]initWithCapacity:len];
for(int j =0; j<len ;j++)
{
...
...
[nArray addObject:[folksIDArray objectAtIndex:j]];
NSLog(#"FID Element=%#", nArray);
}
self.infos = mArray;
[super viewDidLoad];
}
And for this particular code, i am getting the following response:
FID Element=(
400386528950544,
162622322666106,
643171434889706
)
Now, I have a table view in which i have one button for each row and i am able to display the first and last names in each row. What I want now is that whenever I click the button, the unique id for that particular name should be saved in the tag so that i can send that id to the server on button click action.
Please help me out.
Here, I assume that you can make array of unique id array and this array should be declare in .h file or should be class member. Than use following code.
-(IBAction)buttonClicked1:(id *)sender{
NSString *UIDString = [uidarray objectAtIndex:[sender tag]]; // uidarray is unique id array
NSLog(#"uid for particular button=%#", UIDString);// this will give you kid for button that you tapped or clicked.
}
I have one Idea for your requirement...
In TableView Delegate Method.....
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
.............your another code........
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, 14, 14);
button.frame = frame; // match the button's size with the image size
[button setBackgroundImage:image forState:UIControlStateNormal];
// set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
return cell;
}
after paste this method ...
- (void)checkButtonTapped:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:Yourtableview];
NSIndexPath *indexPath = [Yourtableview indexPathForRowAtPoint: currentTouchPosition];
if (indexPath != nil)
{
[self tableView: Yourtableview accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}
and also in accessoryButtonTappedForRowWithIndexPath Delegate method of tableview....
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *item = [self.arrTypes objectAtIndex:indexPath.row];//sel.arrTypes is Array Data..use your Data here and
....... do somthing here which you want ......
}
Tag is one way another way is sender superview. Refer below code (Not require to set tag)
- (IBAction)clickedButton:(id)sender
{
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview;
UITableView *tableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
NSString* id = [Array objectAtIndex:indexPath.row];
}
and if you are using tag then make sure tag must be unique.
use this UIButton* btn.....
btn.tag.
and when button pressed
UIButton *button = (UIButton*)sender;
thetatosendserver = button.tag

How to get UITableview cell.textlabel.text value from button click?

i am a newbie to iphone development.
I am working on a project where i am having a UItableview , i placed a button in each row .
Now my UItableView have a cell.textlabel, detailLabel, and a button placed programatically.
In cell.textlabel i have some values from json(each label have different values) and just at the right corner of each row , i placed a button.
Now i want the cell.textlable.text value of that row only whose button is pressed.
I am getting the same value for each button.
So , my question is , how to get labeltext value of the specific row whose button is pressed ?
attach a tag with your button during its creation e.g. button1.tag = 9999;
in your button click action grab the button as sender
-(void)buttonaction:(UIButton*)sender
{
UITableViewCell * selectedCell = nil;
for(UITableViewCell *cell in [tableView visibleCells])
{
if([cell viewWithTag:9999] == sender)
{
selectedCell = cell;
break;
}
}
//do whatever you like with selected cell now.
}
I hope it helps!!!
Solved like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UIButton *tableCellButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect]retain];
tableCellButton.frame = CGRectMake(200, 1, 80, 20);
[tableCellButton setTitle:#"showing" forState:UIControlStateNormal];
[tableCellButton addTarget:self action:#selector(shortcutBottonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:tableCellButton];
} NSDictionary *listing = [ self.temp objectAtIndex:indexPath.row];
cell.textLabel.text = [listing objectForKey:#"0"];
return cell;
}
-(IBAction) shortcutBottonClicked:(id)sender{
//this code solved the problem
indexPath = [self.tableView indexPathForCell:(UITableViewCell*)[sender superview]];
mlsid2 = [self.tableView cellForRowAtIndexPath:indexPath].textLabel.text;
}
I think you mean that each row in the table has a button, and any number of them can be pressed. After the user is done pressing buttons for rows, you need to get which rows of data have been pressed.
If I read you correclty then unless your table is static, it will work something like the following:
You need to have a datastructure like the one I'm assuming you have for your UITableview datasource. For example, an NSArray full of NSNumber objects, one corresponding to each row of data. When the button in a row is pressed, the corresponding NSNumber is set 1. When you need it, just iterate through the NSArray of NSNumbers to know the corresponding rows in your table's datasource that had it's button pressed.
One thing to be aware of is that UItableview cells that you see in the UI are normally reused as the user scrolls - at least this is the case if you have a variable amount of data and rows for your table (as opposed to static), so you can't rely on the UI elements, like the button, for remembering the state
in first view .h file
#
class viewController;
#import <UIKit/UIKit.h>
#interface firstViewController : UITableViewController<UITableViewDelegate, UITableViewDataSource> {
NSString *_cellTitle;
}
#end
first view .m file in didSelectRowAtIndex method add this code like
viewController *detailViewController = [[viewController alloc] initWithNibName:#"viewController" bundle:nil];
NSInteger row = [indexPath row];
_rowTitle = [_detailList objectAtIndex:row];
detailViewController._barTitle = _rowTitle ;
or you can do this in buttonPressed method
then in the second view .h section -
#interface viewController : UIViewController {
NSString *_barTitle;
}
#property (nonatomic, retain) NSString *_barTitle;
#end
synthesize this property in implementation section
in .m and under viewDidLoad method
self.navigationItem.title = _barTitle;
don't forget to import second view .h file
hope this helps

iPhone:How to get the button action of a customcell from the viewcontroller?

I use UITableview, using IB I defined a UIButton in a custom cell and some labels, The custom cell subclass already have definitions of IBAction of the button and necessary IBOutlets on it, but I want to handle the button click events in the tableview controller it self but not in the custom cell subclass.
How can I do this? also I need to get which row's button is exactly clicked so I will show the content relavant to it.
I solved problem by addding this into my controller;
[cell.expButton setTag:indexPath.row];
UIButton *button = (UIButton *)[cell expButton];
[button addTarget:self action:#selector(buttonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
For the need of clickable event(touch effect on the subView), I usually do this :
-(void)viewDidLoad{
self.tableView.delaysContentTouches = NO;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// This will do the touch down effect on the subView of your UIButton
for (id obj in cell.subviews)
{
if ([NSStringFromClass([obj class]) isEqualToString:#"UITableViewCellScrollView"])
{
UIScrollView *scroll = (UIScrollView *) obj;
scroll.delaysContentTouches = NO;
break;
}
}
// I need to get which row's button is exactly clicked so I will show the content relavant to it.- here it is
UIButton *btn = (UIButton*)[cell viewWithTag:200];
// btn = cell.myButton; If you are connected with the IBOutlet
[btn setTag:200 + indexPath.row];
[self.btnPlay addTarget:self action:#selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)btnAction: (id)sender{
UIButton *btn = (UIButton *)sender;
NSLog(#"Selected subView of the Row is %d th tag", btn.tag-200);
// You can get the UITableViewCell using the tag property
selectedIP = [NSIndexPath indexPathForRow:btn.tag - 200 inSection:1;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIP];
// Do the relevant code
}
the way how you want to do this is right (how MVC have to coded clean) - thats beautiful!
To make it more efficent you have to use delegation - thats the best way how to do this!
Here a way how you can do this (e.g. in swift).
https://stackoverflow.com/a/29920564/1415713

How to identify each button in table row?

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.