- (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
Related
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];
}
In my UITableView "tableview" I added checkboxes in each row using UITableView default functionality.
- (void)viewDidLoad {
[tableview setEditing:YES animated:YES];
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 3;
}
I can select only Multiple checkboxes.But I want to select all the checkboxes using a button click.I can use didSelectRowAtIndexPath to loop through all the rows and get the contents but the checkboxes stays unchecked.
- (IBAction)selectallbutton:(id)sender {
NSInteger nRows=[arr count];
for(int i=0;i<nRows;i++){
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[self tableView:tableview didSelectRowAtIndexPath:indexPath];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",[arr objectAtIndex:indexPath.row]);
}
Is it possible to check them all using this approach or should I try another way?
try this,
- (IBAction)selectallbutton:(id)sender {
NSInteger nRows=[arr count];
for(int i=0;i<nRows;i++){
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
UITableViewCell *cell = [tableview cellForRowAtIndexPath:indexPath];
[cell setSelected:YES animated:NO]; //you can change animated:YES if needed
}
}
I'm trying to insert a row at the top of UITableView, but it crashes in the last line where I declare the endUpdating. This is the code I'm using and I'm using a button outside the table to insert row.
[comments insertObject:comment atIndex:0];
[self.commentsTableView beginUpdates];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.commentsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.commentsTableView endUpdates]; //here crashes with "assertion failure"
I know I can just do insert in array and reload, but I want to do it with animation.
Thank you in advance.
This is my cell for row method
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CommentCell";
// Similar to UITableViewCell, but
ListingCommentTableViewCell *cell = (ListingCommentTableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[ListingCommentTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.commenterLabel.text = [[comments objectAtIndex:indexPath.row] objectForKey:#"user"];
[cell.commenterLabel sizeToFit];
cell.commentLabel.text = [[comments objectAtIndex:indexPath.row] objectForKey:#"text"];
[cell.commentLabel sizeToFit];
cell.lineView.frame = CGRectMake(5 , cell.commentLabel.frame.origin.y + cell.commentLabel.frame.size.height+ 5, cell.frame.size.width-20, 1);
cell.dateLabel.text = [Utils formatCommentDate:[[comments objectAtIndex:indexPath.row] objectForKey:#"createdOn"]];
return cell;
}
THis is my cell height method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
int height = [Utils findHeightForText:[[comments objectAtIndex:indexPath.row] objectForKey:#"teksti"] havingWidth:screenWidth - 40 andFont:[UIFont fontWithName:#"Ubuntu" size:14]];
height += 25;
return height + 5;
}
and my number of rows method
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
return [comments count];
}
This is how I insert objects to UITableView with animation.
-(void)updateMethod {
[self.commentsTableView beginUpdates];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:0];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[comments insertObjects:[NSArray arrayWithObjects:comment, nil] atIndexes:indexSet];
[self.commentsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.commentsTableView endUpdates];
}
You should check numberOfRowsInSection and be sure it reflect your comments.count
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return comments.count;
}
Also all UI updates must be done on the main thread, if you call your update method in different thread there is a change you can see that error.
You should update data source array inside animation block:
[self.commentsTableView beginUpdates];
[comments insertObject:comment atIndex:0];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.commentsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.commentsTableView endUpdates];
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]];
}
I'm using a custom table view cell with a stepper and a label.
But when i check the value of the stepper it increases only once for every 2 presses.
What is the problem?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cellData";
ItemCell *cell = [self.myTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[ItemCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.stepper.tag = indexPath.row;
cell.countLabel.text = [NSString stringWithFormat:#"%g",cell.stepper.value];
NSLog(#"value = %g",cell.stepper.value);
cell.itemLabel.text = [self.groceryItems objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)valueChanged:(id)sender
{
UIStepper *step = sender;
NSIndexPath *index = [NSIndexPath indexPathForRow:step.tag inSection:0];
NSArray *rowsToReload = [NSArray arrayWithObject:index];
[self.myTableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:NO];
}
try to add this to your valueChanged Method:
[self.myTableView beginUpdates];
[self.myTableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:NO];
[self.myTableView endUpdates];