How to pass NSIndexPath object with addTarget method? - ios

I want to pass NSIndexPath to #selector.
So I used following code, but there is no argument like withObject.
How can I do it?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
// User taps expanded row
if (selectedIndex == indexPath.row){
selectedIndex = -1;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
}
// User taps different row
if (selectedIndex != -1){
NSIndexPath *prevPath = [NSIndexPath indexPathForRow:selectedIndex inSection:1];
selectedIndex = (int)indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:prevPath, nil] withRowAnimation:UITableViewRowAnimationFade];
}
// User taps new row with unexpanded
selectedIndex = (int)indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
[favoriteButton addTarget:self action:#selector(favoritePressed:) withObject:indexPath forControlEvents:UIControlEventTouchDown];
[normalButton addTarget:self action:#selector(normalPressed) forControlEvents:UIControlEventTouchDown];
[halfButton addTarget:self action:#selector(halfPressed) forControlEvents:UIControlEventTouchDown];
}
-(void)favoritePressed:(NSIndexPath *)path{
}

There is a better way to do this. You can find the touch point on button click and convert that touch point in to your table frame, and through that point you can get indexpath.
-(void)favoritePressed:(UIButton *)sender{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableview];
NSIndexPath *indexPath = [self.tableview indexPathForRowAtPoint:buttonPosition];
}

Try like this:
-(void)favoritePressed:(UIButton *)sender{
//CustomCell : your custom UITableViewCell class name
CustomCell *cell = (CustomCell) [[sender superview] superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
}
NOTE:
If you set button in content view of CustomCell this will work for you otherwise you need to add other superview for getting the cell.

The code below may work for certain condition but your button may be a inside other view inside a cell. In that case you may not find the cell.
CustomCell *cell = (CustomCell) [[sender superview] superview];
It is better to use it like this.
- (void)btnFavoriteTapped:(UIButton *)sender {
id view = [sender superview];
while ([view isKindOfClass:[CustomCell class]] == NO) {
view = [view superview];
}
CustomCell *selectedCell = (CustomCell *)view;
NSIndexPath *indexPath = [self.tableView indexPathForCell:selectedCell];
}

Related

Is it possible to pass multiple objects or data to addtarget in a table view?

I want to pass textview value on btn click on a particular cell index.
my code like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
-----
[cell1.submitCommentBtn addTarget:self action:#selector(leftCommentBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; // here i want to pass textview object or its data
---
}
Try thiss
Using View Hierarchy
- (IBAction) leftCommentBtnClicked:(UIButton *)sender {
UITableViewCell *cell =(UITableViewCell *)sender.superview.superview.superview; //change with your class
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; // using this indexpath you can get data from your datasource array
cell.textView; // this is your textview
}
OR
Using ConvertPoint
- (IBAction) leftCommentBtnClicked:(UIButton *)sender {
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
YourCell *cell = (YourCell *)[self.tableView cellForRowAtIndexPath:indexPath];
cell.textView; // this is your textview
}
- (void)leftCommentBtnClicked:(UIButton*)sender
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:(Your Table Name)];
NSIndexPath *indexPath = [(Your Table Name) indexPathForRowAtPoint:buttonPosition];
}
Here you get IndexPath, so you can get all the value of that particular row.

How to delete the tableview cell without pressing delete button?

- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView1 cellForRowAtIndexPath:indexPath];
UITableViewRowAction *flagAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[tableData removeObjectAtIndex:indexPath.row];
NSLog(#"indexpath %ld",indexPath.row);
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
return #[ flagAction];
}
you can add swipe gesture to table and delete row as shown following.
- (void)viewDidLoad {
UISwipeGestureRecognizer *gestureDeleteRow = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(cellSwipe:)];
gestureDeleteRow.direction = UISwipeGestureRecognizerDirectionRight;
[tableView addGestureRecognizer:gestureDeleteRow];
}
//Swipe Handler Method
-(void)cellSwipe:(UISwipeGestureRecognizer *)gesture
{
CGPoint location = [gesture locationInView:tableView];
NSIndexPath *swipedIndexPath = [tableView indexPathForRowAtPoint:location];
//Delete Row…
[ARRAY removeObjectAtIndex: swipedIndexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:swipedIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
}
Check this Code with swipe table cell with animation
Github Code

Detecting From which Cell , UIButton was pressed in a UITableView

I have two custom UItableViewCell with Same UIButton , How to determine from Which Cell UIButton is called ?
P.S. I Don’t want To use two different methods.
cellForRowAtIndexPath Method.
if (indexPath.row==1) {
static NSString *cellIdentifier = #“CustomeCell1“;
NewsFeedCell1 *cell = (NewsFeedCell1 *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.btnPrivacy.tag = indexPath.row;
[cell.btnPrivacy addTarget:self action:#selector(btnPrivacyClicked:) forControlEvents:UIControlEventTouchUpInside];
}
else
{
static NSString *cellIdentifier = #"CustomeCell2”;
NewsFeedCell2 *cell = (NewsFeedCell2 *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.btnPrivacy.tag = indexPath.row;
[cell.btnPrivacy addTarget:self action:#selector(btnPrivacyClicked:) forControlEvents:UIControlEventTouchUpInside];
}
Button click Methods.
-(IBAction)btnPrivacyClicked:(UIButton *)sender
{
NSLog(#"Privacy Clicked at : %ld",(long)sender.tag);
// Here Determine From Which Cell UiButton Is Clicked.
NewsFeedCell1 *cell = (NewsFeedCell1 *)[self.HomeTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0]];
// *** Use Following code to detect `Cell` ***
CGPoint buttonPosition = [button convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
[self.tableView cellForRowAtIndexPath:indexPath];
Set tag for cell.btnPrivacy.tag=indexPath.row;
and in button action you will get button btnPrivacy tag i.e sender.tag which is cell index.
Try with this.

Push row to top in UItableview in iOS

I have uitableview and it has 1 button "TOP" in each row. I want to when user click on this button, this row has been push on top in Uitableview ( with animation). Can i reuse BVReorderTableView to do that? How can i do that? Thanks much
i am assuming your -cellForRowAtIndexPath loads cell contents from an array such as the one i named arrObjects which:
is an NSMutableArray object
has many NSString objects
something like:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
[cell.textLabel setText:[arrObjects objectAtIndex:indexPath.row]];
UIButton *btnUp = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnUp setFrame:CGRectMake(0, 0, 30, 30)];
//[btnUp setTag:100];
[btnUp setTitle:#"\u261D" forState:UIControlStateNormal];
[btnUp addTarget:self
action:#selector(moveToTop:)
forControlEvents:UIControlEventTouchUpInside];
[cell setAccessoryView:btnUp];
return cell;
}
- (void)moveToTop:(UIButton *)sender
{
UITableViewCell *cell = (UITableViewCell *)sender.superview; //iOS6 prior
//UITableViewCell *cell = (UITableViewCell *)sender.superview.superview; //iOS7
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
//uncomment lines for safety, incase indexPath ever comes nil... prevent the crash
//if (indexPath == nil) {
// return;
//}
//1. move and animate row to top
[self.tableView moveRowAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row
inSection:indexPath.section]
toIndexPath:[NSIndexPath indexPathForItem:0
inSection:indexPath.section]];
//2. make appropriate changes to the datasource
//so that it reflects logically and is not just an aestehtical change
//PRE-NOTE:
//arrObjects is an object of a category on NSMutableArray
//with a custom instance method named -moveObjectFromIndexPath:toIndex:
//uncomment the following line when you are ready with the category
//[arrObjects moveObjectFromIndex:indexPath.row toIndex:0];
}
the category is easy to create, follow:
http://www.icab.de/blog/2009/11/15/moving-objects-within-an-nsmutablearray/
other links to try:
http://adeem.me/blog/2009/05/29/iphone-sdk-tutorial-add-delete-reorder-uitableview-row/
http://learn-iphone-app-development.com/2011/01/31/tables-part-iii-%E2%80%94-re-ordering-moving-cells-and-swipe-to-delete/
have you tried
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
you can use animations if you want so..
You can easy do that like this:
[self.tableView setContentOffset:CGPointMake(0, 0) animated:YES];
or:
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
or:
[self.tableView scrollRectToVisible:CGRectMake(0.f, 0.f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(self.tableView.frame)) animated:YES];
Edit
Sorry, I misunderstood what you meant.
You should do that like this:
[tableView moveRowAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
If you want to tableView scroll to the top immediately after move the cell, you can try the above code.
Edit
// A more detailed description
- (void)buttonHandle:(UIButton *)sender {
// Assuming button is added directly on the cell.
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
[tableView moveRowAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
}

Not able to remove the Custom Cell from UITableView

I am using Custom Cell for UITableView and there is a UIButton on it which should remove the current cell from the table view.
In cellForRowAtIndexPath I am doing
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CellIdentifier";
NSLog(#"Creating Cell");
FADynamicCell *cell= (FADynamicCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([FADynamicCell class])
owner:nil
options:nil] lastObject];
}
currentIndexPath = indexPath;
UIButton *removeButton = [UIButton buttonWithType:UIButtonTypeCustom];
removeButton.tag = indexPath.row +100;
removeButton.frame = cell.removeButton.frame;
removeButton.backgroundColor = [UIColor colorWithRed:255./255 green:65./255 blue: 21./255 alpha:1];
removeButton.titleLabel.font = [UIFont systemFontOfSize:12];
removeButton.titleLabel.textAlignment = NSTextAlignmentCenter;
[removeButton setTitle:#"Remove" forState:UIControlStateNormal];
[removeButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[removeButton addTarget:self action:#selector(removing) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:removeButton];
return cell;
}
And in Function for removing
-(void) removing
{
[TOperations deleteTickerFromGroup:tickerGroupID andTickerSymbol:selectedSymbol];
NSNumber *selectedRowIndex1 = [NSNumber numberWithInteger:currentIndexPath.row];
[tableView1 beginUpdates];
NSIndexPath *previousPath = [NSIndexPath indexPathForRow:selectedRowIndex1.integerValue-1 inSection:0];
[tableView1 endUpdates];
[tableView1 reloadData];
}
Now problem is that it is showing animation on the correct cell but I am not able to remove the custom cell from the table view. And whenever I load the view again i.e. comes from other screen it does not shows the cell on which I have clicked for removing.
Any help will be appreciated...
To delete a row/cell from table view, you need to call the deleteRowsAtIndexPaths:withRowAnimation: method on your UITableView instance.
NSIndexPath *previousPath = [NSIndexPath indexPathForRow:selectedRowIndex1.integerValue-1 inSection:0];
[self.yourTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:previousPath] withRowAnimation:UITableViewRowAnimationFade];
This will update the UI, but remember to remove that row from your data source as well. This will ensure it is deleted completely.
Hope that helps!

Resources