The project I'm working on required me to use a sqlite database, and I've been trying to get swipe to delete to work on my tableView:
[self performSelectorOnMainThread:#selector(removeMovieFromCache:) withObject:[NSNumber numberWithInt:movieId] waitUntilDone:YES];
[db performSelectorOnMainThread:#selector(performQuery:) withObject:[NSString stringWithFormat:#"DELETE FROM movie WHERE id = %d", movieId] waitUntilDone:YES];
[db performSelectorOnMainThread:#selector(performQuery:) withObject:[NSString stringWithFormat:#"DELETE FROM new_movies WHERE new_movie_id = %d", movieId] waitUntilDone:YES];
[self removeMovieFromCache:movieId];
[db performQueryWithFormat:#"DELETE FROM movie WHERE id = %d", movieId];
[db performQueryWithFormat:#"DELETE FROM new_movies WHERE new_movie_id = %d", movieId];
[db performQuery:#"COMMIT"];
That's the code to get rid of something from my database. When I try to apply this to my swipe to delete command of:
-
(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)movieID
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//code goes here
}
}
It just doesn't want to work, what am I doing wrong?
In your tableView Data Source, try implementing this:
(UITableViewCellEditingStyle)tableView:(UITableView*)tableView editingStyleForRowAtIndexPath:(NSIndexPath*)indexPath
{
return UITableViewCellEditingStyleDelete;
}
(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)movieID
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// First delete the row from the table, then delete from the DB, finally reload the date in the table
[theTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
// code to delete from DB
[theTable reloadData];
}
}
(replace "theTable" with whatever you've called your table!)
Related
I have three tableviews inside of one View Controller (their visibility is controlled by a segment control). That said, I only want cells to have the option of being deleted from self.friendsView, and not the other tableviews. I have the following code below in my View Controller, but the ability to swipe and delete a cell is visible on all three of my tableviews, not just self.friendsView. How can I fix this?
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.friendsView) {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSMutableDictionary *nodeData = [[self.myFriendData objectAtIndex:indexPath.row] mutableCopy];
NSString *nid = [nodeData objectForKey:#"nid"];
[nodeData setObject:nid forKey:#"nid"];
NSLog(#"%#",nid);
[self.myFriendData removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[DIOSNode nodeDelete:nodeData success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"node deleted!");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"could not delete node!");
}];
}
}
}
In addition to implementing commitEditingStyle you also need to implement the editingStyleForRowAtIndexPath delegate method.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.friendsView) {
return UITableViewCellEditingStyleDelete;
} else {
return UITableViewCellEditingStyleNone;
}
}
I have a project I have been working on. The code giving me problems worked yesterday and I haven't made any changes to that part of the code since, when I tried to run it today it wasn't working.
The problem is that when I swipe across the cell to delete it it's not detected and commitEditingStyle method is never run.
I also made another project just to test out the commitEditingStyle method and it was working fine. I also cleaned the project(Product -> Clean) and reset the iOS simulator.
What else can I try?
Here's my code, don't worry about NSUserDefaults, that's for saving the changes after you delete the cell.
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES; }
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.taskObjects removeObjectAtIndex:indexPath.row];
NSMutableArray *newTaskObjectsData = [[NSMutableArray alloc] init];
for(Model *task in self.taskObjects)
{
[newTaskObjectsData addObject:[self taskObjectAsPropertyList:task]];
}
[[NSUserDefaults standardUserDefaults] setObject:newTaskObjectsData forKey:USER_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
I Hope it's help you
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.taskObjects removeObjectAtIndex:indexPath.row];
NSMutableArray *newTaskObjectsData = [[NSMutableArray alloc] init];
for(Model *task in self.taskObjects)
{
[newTaskObjectsData addObject:[self taskObjectAsPropertyList:task]];
}
[[NSUserDefaults standardUserDefaults] setObject:newTaskObjectsData forKey:USER_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; // please set automatic animation
}
// here you can reload your tableview
[self.tasksTableView reloadData];
I found out what was wrong! I had another method in the viewController that I was not aware was there.
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
Fixed it by setting the return value to UITableViewCellEditingStyleDelete.
Have friendsviewcontroller in which have uibarbuttonItem to edit friends list and other uibarbuttonitem to create groups for group chatrooms.
Have multiple segue for switching view controllers.
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Groups";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"New" style:UIBarButtonItemStylePlain target:self
action:#selector(actionNew)];
self.tableView.separatorInset = UIEdgeInsetsZero;
chatrooms = [[NSMutableArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([PFUser currentUser] != nil)
{
[self refreshTable];
}
else LoginUser(self);
}
#pragma mark - User actions
- (void)actionNew
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Create New Group" message:nil delegate:self
cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex=
{
if (buttonIndex != alertView.cancelButtonIndex)
{
UITextField *textField = [alertView textFieldAtIndex:0];
if ([textField.text isEqualToString:#""] == NO)
{
PFObject *object = [PFObject objectWithClassName:PF_CHATROOMS_CLASS_NAME];
object[PF_CHATROOMS_NAME] = textField.text;
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (error == nil)
{
[self refreshTable];
}
else [ProgressHUD showError:#"Network error."];
}];
}
}
}
- (void)refreshTable
{
[ProgressHUD show:nil];
PFQuery *query = [PFQuery queryWithClassName:PF_CHATROOMS_CLASS_NAME];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (error == nil)
{
[chatrooms removeAllObjects];
for (PFObject *object in objects)
{
[chatrooms addObject:object];
}
[ProgressHUD dismiss];
[self.tableView reloadData];
}
else [ProgressHUD showError:#"Network error."];
}];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [chatrooms count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
PFObject *chatroom = chatrooms[indexPath.row];
cell.textLabel.text = chatroom[PF_CHATROOMS_NAME];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
PFObject *chatroom = [chatrooms objectAtIndex:indexPath.row];
[chatrooms removeObjectAtIndex:chatroom];
//[chatrooms removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
PFObject *chatroom = chatrooms[indexPath.row];
NSString *roomId = chatroom.objectId;
CreateMessageItem([PFUser currentUser], roomId, chatroom[PF_CHATROOMS_NAME]);
ChatView *chatView = [[ChatView alloc] initWith:roomId];
chatView.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:chatView animated:YES];
}
Deleted row in table view reappears when navigate back to the TableView
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
PFObject *chatroom = [chatrooms objectAtIndex:indexPath.row];
[chatrooms removeObjectAtIndex:chatroom];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
Im unable to locate what piece of code i m missing or what exactly i m doing wrong.
If anyone can please point out to that.
Will appreciate so much.
Thanks.
When committing deletion, your code removes objects from chatrooms which is data source of the table view in your case, but this happens in your app's memory, the source from which chatrooms is populated does not change. Thus, speaking in MVC, the app's model state is not updated after the view's state is changed.
Every time the table view is showed up, your code populates chatrooms in refreshTable, if the model's state hasn't been changed, the code gets same list as before, thus the table view doesn't change.
EDIT: Instead of using another approach to refresh the table view, you need to think about what does your app do in this table view. If user can delete stuff in the table view, should your app update model (This model can be a local or remote database, a property list file, etc.) too? If yes, then update model when user inserts or deletes rows in the table view; well, if not, then you are asking a question that is not a problem, or maybe the table view should turn off editing.
EDIT1:
If you do need to update data, based on your code, you may need to do something like this:
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
PFObject *chatroom = [chatrooms objectAtIndex:indexPath.row];
[chatrooms removeObjectAtIndex:indexPath.row];
PFQuery *query = [PFQuery queryWithClassName:PF_CHATROOMS_CLASS_NAME];
[query deleteChatroom:chatroom];
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
That is, you may need to implement method deleteChatroom: of class PFQuery.
I am trying to delete a row in a UITableView (PFQueryTableViewController). The object deletes in the class, but is only reflected in the table when I refresh the table. Here is the code I am using.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[tableView reloadData];
}];
}
}
Sussed it.
Instead of [tableView reloadData], I've used [self loadObjects].
However, the usual delete animation is not there.
You have to make all UI updates in main thread.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[tableView deleteRowsAtIndexPaths:#[indexPath]withRowAnimation:UITableViewRowAnimationFade];
}];
}
}
After deleting a row, it is still showed.
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
Audio *current = [logic findAudioByRow:indexPath.row];
[logic deleteAudio:current callback:^{
dispatch_async(dispatch_get_main_queue(), ^{
//some audio player logic that does not important for the topic
});
}];
}
this method calls that function:
-(void)deleteAudio:(Audio *)audio callback:(voidCallback)callback
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString * ownerId = [NSString stringWithFormat:#"%ld", [audio.owner_id integerValue]];
NSString * audioId = [NSString stringWithFormat:#"%ld", [audio.aid integerValue]];
APIData *apiData = [[APIData alloc] initWithMethod:DELETE_AUDIO_BY_ID user:[[UserLogic instance] currentUser] queue:requestQueue params:[[NSMutableDictionary alloc] initWithObjectsAndKeys:audioId,#"aid", ownerId, #"oid", nil]];
[APIRequest executeRequestWithData:apiData block:^(NSURLResponse *response, NSData *data, NSError *error) {
}];
callback();
[self updateContent:YES];
});
}
I don't understand when I should call reloadData to update view.
Can't see the delete method in your code. This is how you have to use the delete row methods.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[mySourceArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
When you delete a row of table view also remove the related record from array, then after reload tableview.