I have a tableview with a few custom cells. Inside the first one is a button. When this button is pressed I want to scroll to a certain Section in my tableview. How do I have to link the button action with the tableview?
You can scroll to a certain section with using this function :
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
the example of usage is :
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:indexPath.section]
atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
and for link the button action with tableview you can use protocol in you custom cell
You can make your cell's button a property and in cellForRowAtIndexPath you can set the target in the class that loads the table view so you won't need any delegates. Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"YourCellIdentifier";
YourCustomCell *cell =[tableView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil) {
cell = [YourCustomCell alloc/init method....
[cell.buttonProperty addTarget:self action:#selector(cellButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
//do other stuff with your cell
}
-(void)cellButtonTapped:(id)sender {
UIButton *button = (UIButton*)sender;
YourCustomCell *cell = (YourCustomCell*)button.superview.superview; //if the button is added to cell contentView or button.superview is added directly to the cell
NSIndexPath *path = [yourTableView indexPathForCell:cell];
[yourTableView scrollToRowAtIndexPath:path
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
}
Set up a delegation mechanism back from your cell - when creating the cell, assign it an NSIndexPath and pass it back from the cell when the button is tapped.
So in your UITableViewCell subclass you'll have:
- (IBAction)buttonPressed:(id)sender
{
[self.delegate buttonPressedOnCellAtIndexPath:cell.indexPath]
}
Back in the controller that's the delegate, respond to this method with:
- (void)buttonPressedOnCellAtIndexPath:(NSIndexPath)indexPath
{
[self.tableView scrollToRowAtIndexPath:indexPath];
}
Related
I am working on Prototype TableView Cell where I have two Label over cell and one button behind the cell. I want to hide the second label on Hide Button click. I have tried a lot but did not get any appropriate info, Here is my code for displaying the Labels in Cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"TableCell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
// Configure the cell...
int row = [indexPath row];
cell.EnglishLable.text = _English[row];
cell.UrduLable.text = _Urdu[row];
return cell;
}
Everything is fine, I just need to hide 'UrduLabel' in my Hide IBAction method.
- (IBAction)Hide:(id)sender {
static NSString *simpleTableIdentifier = #"TableCell";
UITableView *tableView = [[UITableView alloc]init];
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:IndexPath];
BOOL *hideLabel;
hideLabel = YES;
[self.tableView reloadData];
UILabel *subtitle = (UILabel *)[cell.contentView viewWithTag:1];
subtitle.hidden = hideLabel;
}
Whats wrong in my Button method?
Try this code
- (IBAction)Hide:(id)sender {
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
TableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.UrduLable.hidden = YES;
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:<any row animation you need>];
UILabel *subtitle = (UILabel *)[cell.contentView viewWithTag:1];
subtitle.hidden = hideLabel;
}
You just need to get the particular cell of which the button is clicked, hide the required label and reload the particular cell. And main thing is you need to get an instance of your prototype cell class, not of UITableViewCell
IN CASE ONE BUTTON IN THE VIEWCONTORLLER FOR ALL CELL
Incase of single button toggling the visibility of the UrduLabel, declare the -(IBAction)hide:(sender)id in the yourviewcontroller.m. connect the IBAction of the button from nib/storyboard to the -(IBAction)hide:(sender)id method.
Then follow the following steps
declare a BOOL property variable or ivar inside the view controller. named willShowUrdu.
implement the hide as following:
-(IBAction)hide:(id)sender
{
willShowUrdu = !(willShowUrdu);
[yourTableView reloadData];
}
inside the cellForRowAtIndexPath:
TableViewCell *cell = //whatever the way you get the cell
cell.UrduLabel.hidden = !willShowUrdu;
Thats how toggle the visibility of all UrduLabel under one IBAction.
IN CASE OF EACH BUTTON IN EACH CELL
There is a better way to de-centralize the control to each cell. Move the -(IBAction)hide:(sender)id method to the implementation in the TableViewCell's implementation.
Add the IBAction from nib/storyboard to the moved -(IBAction)hide:(sender)id method.
Take a IBOutlet of the UrduLabel, as seen in above code, it's already taken.
Then the implementation of -(IBAction)hide:(sender)id would be following:
-(IBAction)hide:(sender)id
{
//put your other logic here (if any)
self.UrduLabel.hidden = YES;
}
Welcome to IOS, Happy coding.
I am displaying a TabelCell that has images, button, UIView. When click the button it has to show UIView.
UIView is displaying but the problem is, if I click the button in first cell instead of displaying the UIView in the first cell, it is displaying the second cell or in some other cell. I don't know why this is happening.
The code is given below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"HomeTablecell";
cell = (HomeTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.vEdit.hidden=TRUE; //UIView hidden initially
[cell.editButton addTarget:self action:#selector(EditButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; //When this button is clicked cell.vEdit become visible
}
-(void)EditButtonClicked:(UIButton*)sender
{
cell.vEdit.hidden=FALSE;
}
The answer for my question is FPPopover, when I use that control, the view is displaying exactly in the position I wanted
https://github.com/50pixels/FPPopover/
1: make sure the cell is referenced correctly(for instance I added tag to the button clicked)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"HomeTablecell";
cell = (HomeTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.vEdit.hidden=YES; //UIView hidden initially
cell.editBUtton.tag = indexPath.row //suppose has 1 section, you can customise the tag rule based on section/row
[cell.editButton addTarget:self action:#selector(EditButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; //When this button is clicked cell.vEdit become visible
}
-(void)EditButtonClicked:(UIButton*)sender
{
HomeTableCell* theCell = self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0];
theCell.vEdit.hidden =NO;
}
2: Make sure UIView is hidden in your customised cell class for reused cell
//Your cell class
- (void)prepareForReuse {
[super prepareForReuse];
self.vEdit.hidden=YES;
}
When I select one button in my UItableView other buttons lower down are also clicked. I am using target action on a button in a custom tableview and changing the title of sender in the method. Why is this clicking one button selecting multiple UIButtons? Any help/suggestions would be greatly appreciated.
EDIT: I am using a sectioned tableview
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// Configure the cell...
[cell.likeButton addTarget:self action:#selector(likeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cell.likeButton.tag = indexPath.section;
return cell;
}
-(void)likeButtonPressed:(UIButton *)sender {
NSLog(#"%d",sender.tag);
[sender setTitle:#"Pressed" forState:UIControlStateNormal];
}
In your PostTableViewCell.h define a Delegate
#protocol HandleCellInteractionDelegate <NSObject>
-(void) didPressButton:(NSString*)action forCell:(UITableViewCell *)theCell;
#end
In TableView.h register as a Delegate for this protocol
<HandleCellInteractionDelegate>
In TableView.m file add the delegate handler
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// Create cell
....
cell.delegate = self;
if (self.qObjects current object's selection state == selected)
enable button
else
disable button
}
Add the function for protocol
#pragma mark HandleCellInteractionDelegate
-(void) didPressButton:(NSString*)action forCell:(UITableViewCell *)theCell{
// Now here you have access to your cell again. And you can update the cell's button text as needed
// Here save selection state in data model.. in self.qObjects <==
cell.questionTextView.text = #"bla bla";
}
In your uitableviewcell subclass, make sure you are only adding a button to the cell during init. Otherwise you will add an additional button to the cell each time the tableviewcontroller calls dequeueReusableCellWithIdentifier.
Try This:
// Add a property to your custom cell to hold the indexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// Configure the cell...
cell.indexPath = indexPath;
return cell;
}
And in your cell subclass wire up an action method, something like this:
- (IBAction)buttonAction:(id)sender {
NSLog(#"indexPath: %#", self.indexPath);
}
i think you have Multiple Rows in a section so all button of that section get selected
use
cell.likeButton.tag = indexPath.row;
instead of
cell.likeButton.tag = indexPath.section;
I am using a tableView which loads a custom UITableViewCell with a "Tap" button inside it. A method is called when user clicks the button.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{...
[btnRowTap addTarget:self action:#selector(didButtonTouchUpInside:) forControlEvents:UIControlEventTouchDown];
...
return cell;
}
In the didButtonTouchUpInside method, Im trying to retrieve the value of row selected in the following way:
-(IBAction)didButtonTouchUpInside:(id)sender{
UIButton *btn = (UIButton *) sender;
UITableViewCell *cell = (UITableViewCell *)btn.superview;
NSIndexPath *indexPath = [matchingCustTable indexPathForCell:cell];
NSLog(#"%d",indexPath.row);
}
The problem is that on clicking button at any row, I am getting the same value of 0 every time.
Where am I going wrong?
You must NOT rely on the view hierarchy of a UITableViewCell. This approach will fail in iOS7, because iOS7 changes the view hierarchy of the cell. There will be an additional view between your button and the UITableViewCell.
There are better ways to handle this.
Convert the button frame so it is relative to the tableview
ask the tableView for the indexPath at the origin of the new frame
.
-(IBAction)didButtonTouchUpInside:(id)sender{
UIButton *btn = (UIButton *) sender;
CGRect buttonFrameInTableView = [btn convertRect:btn.bounds toView:matchingCustTable];
NSIndexPath *indexPath = [matchingCustTable indexPathForRowAtPoint:buttonFrameInTableView.origin];
NSLog(#"%d",indexPath.row);
}
set Button tag in to cellForRowAtIndexPath method Befor setting Method like
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{...
btnRowTap.tag=indexPath.row
[btnRowTap addTarget:self action:#selector(didButtonTouchUpInside:) forControlEvents:UIControlEventTouchDown];
...
return cell;
}
and your tapped cell getting like this:-
-(IBAction)didButtonTouchUpInside:(id)sender{
{
UIButton *button = (UIButton*)sender;
NSIndexPath *indPath = [NSIndexPath indexPathForRow:button.tag inSection:0];
//Type cast it to CustomCell
UITableViewCell *cell = (UITableViewCell*)[tblView1 cellForRowAtIndexPath:indPath];
NSLog(#"%d",indPath.row);
}
try like this,if you are adding button to cell content view then use below code.
UITableViewCell *buttonCell = (UITableViewCell *)sender.superview.superview;
UITableView* table1 = (UITableView *)[buttonCell superview];
NSIndexPath* pathOfTheCell = [table1 indexPathForCell:buttonCell];
int rowOfTheCell = [pathOfTheCell row];
int sectionOfTheCell = [pathOfTheCell section];
btn.superview is contentView of UITableviewCell. Use btn.superview.superview instead.
if you already knew the value inside the cell, then
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *currentCell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
if ([currentCell.textLabel.text isEqualToString:#"Your Cell Text value" ]){
//Do theStuff here
}
}
here is the code for your ibAction.you dont need to set any tag or anything else
-(IBAction)didButtonTouchUpInside:(id)sender{
NSIndexPath *indexPath =
[tbl
indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
}
I want to change a UIButton text to the selected cell in a UITableView. Normally this would be done like this.
TableView.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if([self.delegate respondsToSelector:#selector(ButtonText:)]) {
[self.delegate ButtonText:selCell.textLabel.text];
}
}
ViewController.m:
- (void)dateSpecifiedButtonText:strText2
{
[self.dateSpecifiedButton setTitle:strText2 forState:UIControlStateNormal];
}
This is working when I select the cell but what I want is to change the button to the cell when you click on another button. So I need to rewrite this method without using didSelectRowAtIndex but I have no idea how.
If you know the indexPath of the cell in which button is
UITableViewCell *cell = [self.tableView cellForIndexPath:indexPath];
If you have just added button to contentView of cell give a unique tag to the button
UIButton *button = (UIButton *)[cell.contentView viewForTag:55];
Now you have the instance of button, set the text to it.