I'd like to implement a "swipe to delete" option to a tableview. I added the "commitEditingStyle" method and it triggers the swipe and a red box with "delete" shows, but I can't work out what should be inside that method. Any help?
Here's the code:
#import "NotificationTableView.h"
#import "NotificationTableViewCell.h"
#interface NotificationTableView () <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, strong) NSMutableDictionary* heights;
#end
#implementation NotificationTableView
-(void)awakeFromNib{
UINib *nib = [UINib nibWithNibName:#"NotificationTableViewCell" bundle:nil];
[self registerNib:nib forCellReuseIdentifier:#"NotificationTableViewCell"];
[self registerNib:nib forCellReuseIdentifier:#"NotificationTableViewCellSize"];
self.dataSource = self;
self.delegate = self;
self.estimatedRowHeight = 86;
self.rowHeight =
// (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) ? UITableViewAutomaticDimension :
86;
self.tableFooterView = [UIView new];
_heights = [NSMutableDictionary new];
}
-(void)setNotifications:(NSArray *)notifications{
_notifications = notifications;
[self reloadData];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[self reloadData];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return self.notifications.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NotificationTableViewCell* cell = [self dequeueReusableCellWithIdentifier:#"NotificationTableViewCell"];
[cell configureCellWithNotification:self.notifications[indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Notification* not = self.notifications[indexPath.row];
[self.notificationDelegate notificationTapped:not];
}
#end
Do not call reloadData in addition to deleteRowsAtIndexPaths:. Just do one.
You first need to update the data model used by your data source. In this case you need to remove the corresponding row from the self.notifications array. This means that you need a mutable array.
You don't need the calls to beginUpdate/endUpdate since you are only making a single call to modify the table view.
Try this:
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Get the notification here
Notification* not = self.notifications[indexPath.row];
//Remove item in array
[self.notifications removeObjectIdenticalTo:not];
// Also remove that row from the table view with an animation
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
Related
I used two(canEditRowAtIndexPath and commitEditingStyle ) methods for delete rows based on index, whenever I went to next view and coming back to the table view deleted rows are again appeared.
How can I delete the rows permanently in table view? it would be very helpful to me.
Seems like you just delete the data from UI, so you got the problem.
You must delete the data from your source and UI at the same time.
Just reference this code:
#interface ViewController ()
#property UITableView* tableView;
#property NSMutableArray* dataArray;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_dataArray = [[NSMutableArray alloc] init];
for (int i = 0; i<10; i++) {
[_dataArray addObject:[NSString stringWithFormat:#"Test%d",i]];
}
_tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:_tableView];
_tableView.editing = true;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"MyTableCell"];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyTableCell"];
}
cell.textLabel.text = [_dataArray objectAtIndex:indexPath.row];
return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return true;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Delete data from source
[_dataArray removeObjectAtIndex:indexPath.row];
//Delete row from UI
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}
#end
Hope it can help you.
Use NSMutableArray as your UITableView's datasource.
In commitEditingStyle Delegate....
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[datasourceArray removeObjectAtIndex:indexPath.row];
}
}
Please guide me in passing data. My storyboard contains two tabbars. In first view I put two buttons by selector in navigationbar that add and remove objects from bookmark. It's not a problem until here. When I change my tabbar to show updated bookmark database in tableview I see duplicated object in rows. I used
- (void)viewWillAppear:(BOOL)animated
and
[tableview reloadData];
but still it shows duplicated object. this is my second class code to show updated data
#implementation BookmarkViewController
#synthesize data , tableData , tblView ;
- (void)viewDidLoad{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
sql = [[SQLiteManager alloc]initWithDatabaseNamed:#"datadic.db"];
bookmarkQuery = #"SELECT EN FROM table WHERE BOOKMARK IS 1";
res = [sql getRowsForQuery:bookmarkQuery];
tableData = [[NSMutableArray alloc]initWithArray:[res valueForKey:#"EN"]];
NSLog(#"%#" , tableData);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
indexRow = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
tblView = [[UITableView alloc]init];
static NSString *myIdentifier = #"CELL";
myCell = [tblView dequeueReusableCellWithIdentifier:myIdentifier];
if (myCell == nil) {
myCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: myIdentifier];
}
[tblView reloadData];
myCell.textLabel.textColor = [UIColor blueColor];
myCell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return myCell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [tableData count];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
[tableData removeObjectAtIndex:indexPath.row];
[tblView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
#end
The problem is most likely that you are instantiating a spare copy of UITableView every time [cellForRowAtIndexPath] is called. You call both [reloadData] as well as [deleteRowsAtIndexPaths] on this copy, which doesn't do anything.
Try this revised code (I'm assuming BookmarkViewController is a subclass of UITableViewController):
#implementation BookmarkViewController
#synthesize data , tableData , tblView ;
- (void)viewDidLoad{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
sql = [[SQLiteManager alloc]initWithDatabaseNamed:#"datadic.db"];
bookmarkQuery = #"SELECT EN FROM table WHERE BOOKMARK IS 1";
res = [sql getRowsForQuery:bookmarkQuery];
tableData = [[NSMutableArray alloc]initWithArray:[res valueForKey:#"EN"]];
NSLog(#"%#" , tableData);
[tblView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
indexRow = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
static NSString *myIdentifier = #"CELL";
myCell = [tableView dequeueReusableCellWithIdentifier:myIdentifier];
if (myCell == nil) {
myCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: myIdentifier];
}
myCell.textLabel.textColor = [UIColor blueColor];
myCell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return myCell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [tableData count];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
[tableData removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
#end
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.effectsTableView beginUpdates];
Effect *effectToBeDeleted =self.effectsArray[indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
[self.effectsArray removeObjectAtIndex:indexPath.row];
[self.effectsTableView endUpdates];
}
}
The above function should in theory delete the rows as they are slided and the delete button is pressed. However the row does not delete instead is visible even after the
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
is called. And after the user scrolls to the bottom of the UITableView, while loading the last row, the app obviously crashes with "*** -[__NSArrayM objectAtIndex:]: index 9 beyond bounds [0 .. 8]" error since one of the objects has been deleted from the array.
the cellForRowAtIndexPath is as follows:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.effectsArray)
{
[self loadEffectsInArray];
}
static NSString *cellIdentifier = #"EffectsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
Effect *effectCellEffect = [self.effectsArray objectAtIndex:indexPath.row];
NSString *effectCellText = effectCellEffect.name;
[cell.textLabel setText:effectCellText];
cell.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
return cell;
}
Below is the entire .m file for better context:
#import "EffectsManagementTableViewController.h"
#import "Effect+Manage.h"
#import "VLOGAppDelegate.h"
#import "AddEffectViewController.h"
#import "EffectFilterProperty+Manage.h"
#import "Effect.h"
#interface EffectsManagementTableViewController ()
#property (strong, nonatomic) IBOutlet UITableView *effectsTableView;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, strong) NSMutableArray *effectsArray;
#property (nonatomic, strong) NSString *currSelectedRowTitle;
#end
#implementation EffectsManagementTableViewController
-(NSString *)currSelectedRowTitle
{
if(!_currSelectedRowTitle)
{
_currSelectedRowTitle = #"";
}
return _currSelectedRowTitle;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
VLOGAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
self.managedObjectContext = appDelegate.managedObjectContext;
self.effectsTableView.dataSource = self;
self.effectsTableView.delegate = self;
}
-(void)viewWillAppear:(BOOL)animated
{
[self loadEffectsInArray];
[self.effectsTableView reloadData];
[self.effectsTableView setNeedsDisplay];
[self.effectsTableView setNeedsLayout];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (!self.effectsArray)
{
[self loadEffectsInArray];
}
return [self.effectsArray count];
}
//4
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.effectsArray)
{
[self loadEffectsInArray];
}
static NSString *cellIdentifier = #"EffectsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
//6
Effect *effectCellEffect = [self.effectsArray objectAtIndex:indexPath.row];
NSString *effectCellText = effectCellEffect.name;
//7
[cell.textLabel setText:effectCellText];
//[cell.detailTextLabel setText:#"5 stars!"];
cell.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
//cell.backgroundColor = [UIColor blackColor];
//cell.textLabel.textColor = [UIColor whiteColor];
//cell.detailTextLabel.textColor = [UIColor grayColor];
//cell.textLabel.highlightedTextColor = self.effectsTableView.tintColor;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.effectsTableView beginUpdates];
Effect *effectToBeDeleted =self.effectsArray[indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
[self.effectsArray removeObjectAtIndex:indexPath.row];
//[self loadEffectsInArray];
[self.effectsTableView endUpdates];
//[self.effectsTableView reloadData];
//[self.effectsTableView setNeedsLayout];
//[self.effectsTableView setNeedsDisplay];
}
}
-(void)deleteEffectWithName:(NSString *)effectName
{
NSArray *efpForEffectToBeDeleted = [EffectFilterProperty getEffectFilterPropertiesForEffectName:effectName forImmediateEngagement:NO forManagedObjectContext:self.managedObjectContext];
Effect *effectToBeDeleted = [Effect getEffectWithName:effectName forManagedObjectContext:self.managedObjectContext];
for (int i = 0; i < efpForEffectToBeDeleted.count; i++)
{
EffectFilterProperty *currEFP = efpForEffectToBeDeleted[i];
currEFP.relatedEffect = nil;
currEFP.relatedFilterProperty = nil;
[self.managedObjectContext deleteObject:currEFP];
}
[self.managedObjectContext deleteObject:effectToBeDeleted];
NSError *err = nil;
[self.managedObjectContext save:&err];
if (err != nil) {
//Problem while saving
}
}
-(void)loadEffectsInArray
{
self.effectsArray = [[Effect getAllEffectsForManagedObjectContext:_managedObjectContext] mutableCopy];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Effect *effectCellEffect = [self.effectsArray objectAtIndex:indexPath.row];
self.currSelectedRowTitle = effectCellEffect.name;
[self performSegueWithIdentifier:#"PushedByTableView" sender:self];
}
/*
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<##"reuseIdentifier"#> forIndexPath:indexPath];
// Configure the cell...
return cell;
}
*/
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"PushedByTableView"])
{
AddEffectViewController *destinationViewController = segue.destinationViewController;
NSString *selectedRowText = self.currSelectedRowTitle;
destinationViewController.effectToManage = [Effect getEffectWithName:selectedRowText forManagedObjectContext:self.managedObjectContext];
}
}
#end
What am I doing wrong here?
where are you beginning your updates, please add
[self.effectsTableView beginUpdates];
before deleting your row and no need of reloading the table when you are writing the begin updates and end updates.
Please don't remove the object from array before deleting the row.
IT'S WORKING
At end of your commitEditingStyle method add this line this will help you
[TableViewForFirstView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
try this code to add beginUpdatesmethod before delete called
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.effectsTableView beginUpdates];
Effect *effectToBeDeleted =self.effectsArray[indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
[self.effectsArray removeObjectAtIndex:indexPath.row];
[self loadEffectsInArray];
[self.effectsTableView endUpdates];
}
Try this code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
Effect *effectToBeDeleted =[self.effectsArray objectAtIndex:indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsArray removeObjectAtIndex:indexPath.row];
[self loadEffectsInArray];
[self.effectsTableView reloadData];
}
As this message, it's crash for reason out of bound, so try check the array index before assign:
Effect *effectToBeDeleted = self.effectsArray > indexPath.row ? self.effectsArray[indexPath.row] : nil;
And
if(self.effectsArray.count > indexpath.row)
[self.effectsArray removeObjectAtIndex:indexPath.row];
else
NSlog("out of bound");
I'm just practicing with UITableView.
Here is what I did so far.
made cells with xib.file from scratch.
Data is stored in P-list.
Using [ MutableCopy] and convert array into mutableArray
It looks little strange but I made the delegate connection using storyboard ,so there's no "self.tableView.delegate = self" line here.
Now the problem is I can delete the objects in the mutableArray but not on UI. The row I selected is remained on the table.
I know "- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath" delegation method works but something goes wrong.
Any Advice is appreciated! Thanks:)
![#import "ViewController.h"
#import "Model.h"
#import "SimpleTableCell.h"
#interface ViewController ()
{
NSMutableArray *_recipesMC;
NSMutableArray *_imagesMC;
Model *_model;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
\[super viewDidLoad\];
// Do any additional setup after loading the view, typically from a nib.
Model *model = \[\[Model alloc\] init\];
\[model getBack\];
NSArray *recipes = model.recipes;
NSArray *images = model.imagesArray;
_recipesMC = \[recipes mutableCopy\];
_imagesMC = \[images mutableCopy\];
}
- (void)didReceiveMemoryWarning
{
\[super didReceiveMemoryWarning\];
// Dispose of any resources that can be recreated.
}
# pragma mark delegat patern
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return \[_recipesMC count\];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)\[tableView dequeueReusableCellWithIdentifier:cellIdentifier\];
if(cell == nil)
{
NSArray *nib = \[\[NSBundle mainBundle\] loadNibNamed:#"Empty" owner:self options:nil\];
cell = \[nib objectAtIndex:0\];
}
cell.nameLabel.text = \[_recipesMC objectAtIndex:indexPath.row\];
if (indexPath.row < \[_recipesMC count\] - 1)
{
UIImage *image = \[UIImage imageNamed:_imagesMC\[indexPath.row\]\];
cell.thumbnailImageView.image = image;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
# pragma mark delegate touch
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%li",(long)indexPath.row);
UIAlertView *alert = \[\[UIAlertView alloc\] initWithTitle:#"HEY" message:\[NSString stringWithFormat:#"%#",_recipesMC\[indexPath.row\]\] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil\];
\[alert show\];
UITableViewCell *cell = \[tableView cellForRowAtIndexPath:indexPath\];
if (cell.accessoryType !=
UITableViewCellAccessoryNone) {
cell.accessoryType =
UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
\[self performSegueWithIdentifier:#"CellSelectionSegue" sender:self\];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Clicked DELETE BUTTON at %i",indexPath.row);
\[_recipesMC removeObjectAtIndex:indexPath.row\];
\[_imagesMC removeObjectAtIndex:indexPath.row\];
\[self.tableView reloadData\];
NSLog(#"count = %i",\[_recipesMC count\]);
}
# pragma mark Segue
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Segue");
}
#end
I'm pretty sure your self.tableView is nil.
It's because even if you set self as datasource and delegate, your table will work, but here you seems to have create your UITableView *tableView but didn't link it through your interface (if you do it with the builder).
Or you can simply call tableView rather than self.tableView because the delegate protocole gives you the table.
Just do it and it will work. And then, you can try the solution of Szu.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Clicked DELETE BUTTON at %i",indexPath.row);
[_recipesMC removeObjectAtIndex:indexPath.row];
[_imagesMC removeObjectAtIndex:indexPath.row];
[tableView reloadData];
NSLog(#"count = %i",[_recipesMC count]);
}
Yo should call deleteRowsAtIndexPath:wothRowAnimation:
e.g. in my code:
if (editingStyle == UITableViewCellEditingStyleDelete) {
ElKeyValuePair *pair = [self.locationFavoritesKeyArr objectAtIndex:[indexPath row]];
[self.locationFavoritesKeyArr removeObjectAtIndex:[indexPath row]];
ELCarpark *carpark = [self.agglomeration carparkForUid:[pair.val1 intValue]];
[carpark removeFromFavoritesAgglomerationUid:self.agglomeration.uid];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
Adding this code to the method tableView:commitEditingStyle:forRowAtIndexPath should remove the row from the data source and the UI.
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[_recipesMC removeObjectAtIndex:indexPath.row];
[_imagesMC removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:indexPath withRowAnimation:YES];
}
Finally remove the reloadData instruction.
I had my app working fine on iOS 6. With the upgrade I stopped being able to delete rows from my UITableView.
I've a button in my prototype cell.
Here is the button's function:
- (IBAction)deleteCell:(id)sender {
UIButton *btn = (UIButton*) sender;
UITableViewCell *cell = (UITableViewCell*) btn.superview.superview;
NSIndexPath *indexPath = [_tableView indexPathForCell:cell];
if([names count] > 9) {
int index = indexPath.row;
[names removeObjectAtIndex:index];
[photos removeObjectAtIndex:index];
[_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
}
}
The problem is my index variable is always 0.
I tried another solution:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
int index = indexPath.row;
[names removeObjectAtIndex:index];
[photos removeObjectAtIndex:index];
[_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
}
}
This solution doesn't work either. Nothing happens when I swipe right.
Try this sample tutorial,
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *arryData1;
NSMutableArray *arryData2;
IBOutlet UITableView *tableList;
}
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
arryData1 = [[NSMutableArray alloc] initWithObjects:#"MCA",#"MBA",#"BTech",#"MTech",nil];
arryData2 = [[NSMutableArray alloc] initWithObjects:#"Objective C",#"C++",#"C#",#".net",nil];
tableList.editing=YES;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arryData1 count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier= #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = [arryData1 objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [arryData2 objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
int index = indexPath.row;
[arryData1 removeObjectAtIndex:index];
[arryData2 removeObjectAtIndex:index];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableList.editing)
{
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
I quess the problem is you're not reloading data again thus it's staying in cache memory
You can try to reload data with [tableView reloadData]; this method to the below of
[_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
this code line in your second solution.
To show delete button on cell swipe you must implement this delegate method.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
Try this, i hope this will work for you.
Use the tableview commiteditingstyle method to delete a cell/row of the tableviewcontroller.
Here is the workable code snip:
-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[ArrayHoldsCellObj removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Note that the ArrayHoldsCellObj is the Array object you must declare and assign each cell to the area index.
You can set the button tag = cell.index in cellForRowAtIndexPath.
And then
UITableViewCell *cell = (UITableViewCell *)
[tableView cellForRowAtIndexPath:
[NSIndexPath indexPathForRow:btn.tag inSection:0]];
so you can get the index
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
[dataSourceArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}