In my iPhone app, I have to put buttons dynamically along with the scrollView.
Now I need to have button Click events associated with each of the buttons and perform a specific action on each button click.
My buttons have a title which is ASCII art. So creating common IBAction and performing the action based on the button title wont be a easy option in this case.
What can be the other options?
How can I associate the button click event with the specific button?
I think you can use the tag property of UIView.
My program may be like following.
- (NSInteger)encodeTagForButtonID:(NSString *)buttonID;
- (NSString *)decodeButtonIDFromEncodedTag:(NSInteger)tag;
When I create a UIButton, I encode the ID of the button to tag. buttonID may be something meaningful, or it is just an integer, like defined values. The signature of action can be this form: -(void)buttonAction:(id)sender;, and I can retrieve the tag value from sender.
Edit:
For example, in the UITableView's data source method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
/// new an autoreleased cell object
}
// Configure cell
cell.tag = [self encodeTagWithIndexPath:indexPath];
return cell;
}
When I touch this cell, I retrive indexPath from tag.
UIButton is a subclass of UIView, so it has tag too. For example, I made a custom actionSheet, it contains a list of UIButtons. When I push down a UIButton, I need to know which button I pressed. So, I assign the row information to tag.
NSArray *buttonListInActionSheet = ....; ///< UIButton array, a button per row.
for (int idxBtn = 0; idxBtn < [buttonListInActionSheet count]; ++idxBtn) {
UIButton *btn = [buttonListInActionSheet objectAtIndex:idxBtn];
btn.tag = (100 + idxBtn);
}
When I touch the button, I can get the row information by
- (void)buttonTouched:(id)sender {
UIButton *btn = (UIButton *)sender;
NSInteger idxBtn = (btn.tag - 100);
}
Related
I have a table where 5 cells are there. In each cell there is a button. I need to change those buttons dynamically on some conditions. How to change the button dynamically in table view.
What you can do is Write a function which will change the values of the buttons and then you can call that function. After changing button values then use any one of the mentioned method below:
You can use either : [tableview reloadData]; to reload all the table data.
OR
You can reload particular rows using the following method :
[tableview reloadRowsAtIndexPaths: indexPath withRowAnimation:anyKindOfAnimation];
You can query your table view for all visible cells through -visibleCells, get the reference of your button (assuming you have a UITableViewCell subclass with a property for the button) and change them.
First you need to set tags for each buttons. This can be done by
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Your code
cell.Button.tag = indexPath.row;
[cell.Button addTarget:self action:#selector(buttonClick1:) forControlEvents:UIControlEventTouchUpInside];
}
Then you can get the button from this method
- (IBAction)buttonClick1:(id)sender {
int tagNo =[sender tag];
UITableViewCell *cellclicked = [self.tblProfileFollowing cellForRowAtIndexPath:[NSIndexPath indexPathForRow:tagNo inSection:0]];
//Now change the action for the cell
[cellclicked.Button addTarget:self action:#selector(buttonClick2:) forControlEvents:UIControlEventTouchUpInside];
//Your Code
}
You can follow the same steps for - (IBAction)buttonClick2:(id)sender
Now you can track which button was clicked and change the method for that button.
And declare your cell and button strong.
I have UITable which contains some UIButtons. I would like a way to use the label.
The problem I have is that I need two tag labels, one for retrieving the cell in tableviewCellWithReuseIdentifier and configureCell.
Until recently I have been using the UIButton.title to determine which row in the table I selected. The (invisible) text was the row number.
Now I need to use the title for some visible text. How can I still find which row was pressed?
When I press the area outside the button the usual didSelectRowAtIndexPath is called. The hard part is that I want to capture both the UIButton (which calls its own selector) and the row, which I had been finding out from the title. Now I need the title for something else.
I use something like this. This will get you the indexpath in the tableview.
- (IBAction)buttonAction:(id)sender {
UIButton *button = (UIButton *)sender;
CGPoint buttonOriginInTableView = [button convertPoint:CGPointZero toView:tableView];
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:buttonOriginInTableView];
// do something
}
You could subclass UITableViewCell or UIButton and add some properties.
You should implement the UITableViewDelegate protocol.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do something based on selected row (indexPath.row)
}
Implement the UITableViewDelegate protocol. It will help you and do what you need.
didSelectRowAtIndexPath is autmatically called whenever a row is selected in your table.
in your .m file the one with the table view controller if there isn't one there add this method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// NSInteger row = [indexPath row];
// or (indexPath.row)
// do whatever you like with this value which tells you which row is selected.
}
PK
When I click on my tableView's detail-button... I can manage to get the section number, the row number, and even the cell itself... but why is the actual "detail button" unobtainable? (NSLog always displays "(null)" for the button.)
- (void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
int section = indexPath.section;
int row = indexPath.row;
UITableViewCell *aCell = [tableView cellForRowAtIndexPath:indexPath];
UIButton *detailButton = (UIButton *)[aCell accessoryView];
// Why is detailButton null?
NSLog(#"accessory button tapped for row with index path %d x %d \n cell=(%#) \n button=(%#)", section, row, aCell, detailButton);
}
The accessory view is a UIView not a UIButton. Perhaps casting it to a button throws off the description method. Just a guess.
Your best bet is to access the button within the view. Perhaps something like
UIButton* detailBtn = [[UIButton alloc] init];
for (UIButton* detail in aCell.accessoryView.subviews)
{
detailBtn = detail;
}
This assumes you only have your detail button in the accessory view, picks it out of the subview, and creates your references to it in detailBtn :)
I have a UITableView with 15 cells, each with a separate text box in it.
I have implemented UITextViewDelegate and I am able to received changed textview data using textViewDidChange (etc). But I have one big problem still, how do I know WHICH textview sent this, (i.e. in which cell was the textview altered?)
Its interesting to have so much working, yet not know precisely where it comes from.
A whole bunch of code is available if required.
Regards #norskben
Code
// Customize the appearance of table view cells.
- (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];
//Big Text Box
UITextView *detailLabel = [[UITextView alloc] initWithFrame:CGRectMake(30, 80, CONST_Cell_width, 150)];
detailLabel.tag = 20;
[cell.contentView addSubview:detailLabel];
}
UITextView * detailLabel = (UITextView *) [cell.contentView viewWithTag:20];
You can assign tags (integers) to the different views and query the tag number to see which view called the method. Look for the tag property on the view:
tag
The receiver’s tag, an integer that you can use to identify view objects in your application.
#property(nonatomic) NSInteger tag
see here
Not at my development machine, but when you create the UITextView you should be able to assign it a tag. I think it is [myTextView setTag:x]; where x is an integer.
Then, in the TextViewDidChange use
if (textview.tag == x) {
//do something
} else if (textview.tag == y) {
//do something else and so on
}
Hope that helps a little.
The text views pass a reference to themselves in every delegate method so you know which one sent it. To make a connection to the cell, I'd set each text view's tag property to a different value that corresponds to the row of the cell they're in.
Here's an important question: Are your text boxes static, or can they change over time? If they won't change (the user can't alter the number of cells or add more later), then you can declare a new textField for each cell. I have something similar in my apps. I have two text boxes, and depending on which textField is currently active, the delegate does something different.
Declare separate text fields in your header
UITextField *textField1;
UITextField *textField2;
UITextField *textField3;
in the delegate method, use if statement blocks to find out which textField is changing:
if (textField == textField1) {
//do something
} else if (textField == myTextField2) {
//something else
}
Note that this really only works if your view is static.
Hope this helps
Have a great day
When you're searching the UITableView's cells for the event source UITextView, only iterate over the cells that the user can currently see. This can be obtained using the following UITableView method:
- (NSArray *)visibleCells
I am using a custom UITableViewCell class. My cell has multiple buttons (4 to be precise) on it and the button clicks are handled in the UIViewController which uses this cell class.
I was trying to use the button's tag to calculate the row number on which the button was clicked. But doing this causes an issue if a cell was not created and instead uses a free object. In that case the tag and the row number do not match.
Can someone please tell me how I can handle this case? If I give the same tag to all buttons in different rows, how can I identify the row on which the button was clicked?
Thanks a lot.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
MyTableCell *cell = (MyTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// whatever you have now
}
// Set up the cell...
cell.myListViewController = self;
int tag = indexPath.row;
cell.button1.tag = tag;
cell.button2.tag = tag;
cell.button3.tag = tag;
....
}
This code will have a unique tag for buttons in each row. You are setting the tag not in the new cell creation but for all cases, including reuse.