How do I add a custom button on a UITableViewCell, and then delete the cell with that button without using Interface Builder and Custom Cell?
If you really want to add a custom button WITHOUT subclassing, just add the button to the contentView of the cell:
[cell.contentView addSubview:customButton];
You can set all the characteristics of the button: frame, target, selector, etc... Ad then used the above call to add it to the cell.
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
customButton.frame=//whatever
[customButton setImage:anImage forState:UIControlStateNormal];
[customButton setImage:anotherImage forState:UIControlStateHighlighted];
[customButton addTarget:self action:#selector(delete) forControlEvents: UIControlEventTouchUpInside];
//yadda, yadda, .....
You can tag it as well
customButton.tag = 99999;
So you can find it later:
UIButton *abutton = (UIButton*) [cell.contentView viewWithTag:99999];
You will need to decide WHEN to add the button, maybe on cell selection, maybe in editing mode... just put the code in the delegate method of your choice.
If the button's sole purpose is to offer deletion you should look into UITableViewDataSource which has a method called - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath. Implement it like so:
- (BOOL)tableView:(UITableView *)tableView
canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
And then implement:
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Database removal code goes here...
}
To use these methods, let your UITableViewController implement the UITableViewDataSource protocol by doing something like:
MyClass : UITableViewController <UITableViewDataSource>
in your header file, and be sure to remember to set the viewController's datasource to self.
Related
I have a created custom UIButton in UITableView viewForHeaderInSection. Now when i click on the button within the section how will i know which section is clicked? Please help.
when you add button in viewForHeaderInSection , just set tag with section number like bellow.,..
button.tag = section;
and when your button clicked at that time you can get that number with bellow code...
- (IBAction)yourButton_Clicked:(id) sender
{
NSLog(#"Section Number => %d",[sender tag]);
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIbutton *btn =[[UIButton alloc]init];
btn.tag=section;// this tag property will differentiate button for different section
}
by this you can access btn and add event on that burron
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIbutton *button =[[UIButton alloc]init];
button.tag=section;// this tag property will differentiate button for different section
}
In didselectrowatindexpath check for if(index path.section) is equal to the section you want the action.
In my application I created a custom table view cell having a button inside it. I need to do specific actions when each button tapped. At the moment I could add actions to buttons, so that when I tapped, the actions are invoking but I cant identify which button is responsible for that action. How can I do different operations based on user event on buttons ? I could do this in normal way by setting "tag" property and checking using
[sender tag]
but dont know in this case. Thanks in advance.
Example:
[button1 addTarget: target action: #selector(action1) forControlEvents: UITouchUpInside];
[button2 addTarget: target action: #selector(action2) forControlEvents: UITouchUpInside];
[button3 addTarget: target action: #selector(action3) forControlEvents: UITouchUpInside];
Make a for loop and assign each button an incremental tag (based on row number possibly), as well as a single method in the view control that is the target (all buttons get the same selector).
In the called method, extract the tag number and perform the necessary action on it.
You're probably adding buttons to cells in cellForRowAtIndexPath.
If your table has only one section, then it's easy. Simply modify cellForRowAtIndexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// .. create cell
// .. add button
myButton.tag = indexPath.row;
[myButton addTarget: target action: #selector(buttonClicked:) forControlEvents: UITouchUpInside];
return cell;
}
-(void) buttonClicked:(id)sender {
NSLog (#"user clicked button in row %d", [(UIButton *)sender tag]);
// ..do your stuff here
}
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
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
I want to use a UITableView for my settings screen. So that my settings view will look like apple does it, with a group table view, and then the UI elements to let you change settings.
So, it does not seem like the cells are loaded from an array, but seems like each one is customized.
Ideas on how to do this?
For starters, set the tableViewStyle property to UITableViewStyleGrouped.
Then change the data source to provide 2D arrays with the groups you want, instead of a simple array. It's pretty simple, actually.
You will need to customize the row with UIControl types that you want - I assume you're already doing that though.
EDIT:
To add the control to the row, create it when you create the cell.
...
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(0.0f, 5.0f, 30.0f, 30.0f)];
[button setTitle:#"Click Me!" forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button];
...
You can do it without an array. Just use the following methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
and then can use a switch-method to parse thru all rows and sections. Those two lines on the header of the methods on top and you can short it up a bit.
NSUInteger row = [indexPath row];
NSUInteger section = [indexPath section];
Don't forget, that manual tableviews are prone to errors.
cheers Simon