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];
}];
}
}
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 believe this is a simple task, but so far I'm only able to delete the row itself but not the CoreData. The code I'm trying to write - fetch and NSManaged Object is not working, and I'm a bit confused. Can someone help me out? What I've got:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Spot"];
NSManagedObject *managedObject = [request objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:managedObject];
[self.managedObjectContext save:nil];
//delets the row but not the core data
[_locations removeObjectAtIndex:[indexPath row]];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Do it this way and in this order:
Get the object from the data source array by index(path).
Delete the object in the context.
Save the context and check the error.
On success remove the object from the data source array and delete the row in the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObject *objectToDelete = [_locations objectAtIndex:indexPath.row];
[self.managedObjectContext deleteObject: objectToDelete];
NSError *error;
[self.managedObjectContext save:&error];
if (error) {
NSLog(#"Could not save managed object context due to error: %#", error);
} else {
[_locations removeObject:objectToDelete];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
}
There is a problem when I try to delete UITableViewCell in success block of the request.
In my
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
I am making request with AFNetworking
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
After that in success block I am updating UI by dismissing SVProgressHUD and deleting cell:
NSUserDefaults *usd = [NSUserDefaults standardUserDefaults];
[usd removeObjectForKey:#"payViaCreditCard"];
selectedCardID = nil;
[[CreditCardManager sharedCreditCardManager] removeCreditCard:creditCardToDelete];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView reloadData];
In the end my UI not updating and app freezes, when I relaunch the app the data in NSUserDefaults changed.
It would be good if you do either deleteRowsAtIndexPaths:withRowAnimation or tableView reloadData.
[[CreditCardManager sharedCreditCardManager] removeCreditCard:creditCardToDelete];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
OR
[[CreditCardManager sharedCreditCardManager] removeCreditCard:creditCardToDelete];
[self.tableView reloadData];
For deleting cell you should use
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSUserDefaults *usd = [NSUserDefaults standardUserDefaults];
[usd removeObjectForKey:#"payViaCreditCard"];
selectedCardID = nil;
[[CreditCardManager sharedCreditCardManager] removeCreditCard:creditCardToDelete];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//[self.tableView reloadData];
}
}
Any insight would be greatly appreciated.
I have an app with a shared photo stream and I need the user to only be able to swipe and delete their own photo items...my basic code setup works to delete with swipe, but I can't figure out the best way to code so that it verifies first that the PFUser matches as the owner of the PFOject before allowing for swipe and delete
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ PFObject *object = [self.objects objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
}];
}
Grazie,
As per your code you have to manually refresh the table because you have not refreshed the table. Add the code as follows
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Remove the row from data model
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// Add refresh control & reload the tableView.
[self refreshControl];
[tableView reloadData];
}];
}
This worked for me
- (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) {
if (succeeded) {
[self loadObjects];
}
}];
}
}
First off ,in your photo class you need to have a pointer to the user who owns the photo.
Now in your table view controller you have an array of your PFObjects that you called objects.
So to allow the user to delete only his/her photos you could do something like this.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
PFObject* photoObject=self.objects[indexPath.row];
PFUser* owner=photoObject[#"owner"];
[owner fetchIfNeeded];
if ([owner.objectId isEqualToString:[PFUser currentUser].objectId]) {
return YES;
}
else return NO;
}
However a better way to do this is to have a custom class and make your table view controller model that class as the following:
#interface MyPhoto : NSObject <NSCoding>
#property UIImage* photo;
#property PFObject* parseObject;
#property BOOL iOwnThisPhoto;
//Class method to fetch the photo stream from parse and return an array of MyPhoto*
+(NSArray*)fetchStream;
#end
In my table view controller I would have something like this
#interface PhotoStreamVC ()
//Private property
#property NSMutableArray* photos;
#end
#implementation PhotoStreamVC
- (void)viewDidLoad
{
[super viewDidLoad];
//Do background fetch
[self performSelectorInBackground:#selector(fetchPhotoStream) withObject:nil];
}
-(void)fetchPhotoStream
{
self.photos=[MyPhoto fetchStream];
//Reload table view from the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
MyPhoto* photo=self.photoStream[indexPath.row];
return photo.iOwnThisPhoto;
}
#end
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!)