Search code examples
iosobjective-cviewcontrollerdismissekevent

How to dismiss the eventeditviewcontroller when I have allowed editing on eventviewcontroller?


So I present an EKEventViewController with a UINavigationController. From inside the EKEventViewController I am able to edit the event. It presents an EKEventEditViewController. Everything thing works great(cancel/done buttons) except when I delete the event inside the EKEventEditViewController I recieve this

attempt to dismiss modal view controller whose view does not currently appear. self = modalViewController =

Here is my code...

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [CalendarViewController connectExchange];

    if (connectionEx == YES)
    {
        NSDate *dateRepresentingThisDay = [self.sortedDays objectAtIndex:indexPath.section];
        NSArray *eventsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
        EKEventViewController *eventViewController = [[EKEventViewController alloc] init];

        eventViewController.allowsEditing = YES;
        eventViewController.delegate = self;
        EKEvent *event = [eventsOnThisDay objectAtIndex:indexPath.row];
        eventViewController.event = event;

        UINavigationController *navBar = [[UINavigationController alloc]initWithRootViewController:eventViewController];

        [self.navigationController presentViewController:navBar animated:YES completion:nil];
    }
}

- (void)eventViewController:(EKEventViewController *)controller didCompleteWithAction:(EKEventViewAction)action
{
    EKEvent *event = controller.event;

    CalendarViewController * __weak weakSelf = self;
    // Dismiss the modal view controller
    [self dismissViewControllerAnimated:YES completion:^
    {
        if (action == EKEventViewActionDone)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
               NSError *err;
               [self.eventStore saveEvent:event span:EKSpanThisEvent error:&err];
               [self updateEvent:event];
            });
        }
        if (action == EKEventViewActionDeleted)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
               [self deleteEvent:event];
               NSError *error;
               EKEvent *eventRemove = [self.eventStore eventWithIdentifier:event.eventIdentifier];
               [self.eventStore removeEvent:eventRemove span:EKSpanThisEvent error:&error];
            });
        }
        if (action == EKEventViewActionResponded)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
            });
        }

     weakSelf.eventsList = [self fetchEvents];
     [weakSelf.tableView reloadData];
     NSLog(@"Event Updated");
     }];
}

How am I suppose to properly dismiss the ViewControllers after deleting the event via the EKEventEditViewController?


Solution

  • I solved my problem by subclassing EKEventViewController and setting up EKEventEditViewDelegate and EKEventViewDelegate.

    Here is my changed didSelectRow(CalendarViewController.m),

        EditViewController *eventViewController = [[EditViewController alloc] init];
    
        eventViewController.allowsEditing = YES;
        eventViewController.delegate = self;
        EKEvent *event = [eventsOnThisDay objectAtIndex:indexPath.row];
        eventViewController.event = event;
    
        [self.navigationController pushViewController:eventViewController animated:YES];
        self.editingEvent = eventViewController.event;
    

    The EditViewController is my subclass of EKEventViewController.

    In the subclass(EditViewController.m) I added my own edit button with a selector in viewDidLoad,

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        UIBarButtonItem *editItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self.delegate action:@selector(editCalEvent)];
        self.navigationItem.rightBarButtonItem = editItem;
    }
    

    Now back in CalendarViewController.m after adding the EKEventEditViewDelegate and EKEventViewDelegate to the @interface I added new methods

    - (void)editCalEvent
    {
    
         EKEventEditViewController *editController = [[EKEventEditViewController alloc] init];
    
         editController.event = self.editingEvent;
         editController.eventStore = self.eventStore;
         editController.editViewDelegate = self;
    
         [self presentViewController:editController animated:YES completion:nil];
    
    }
    
    - (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction (EKEventEditViewAction)action
    {
         EKEvent *thisEvent = controller.event;
    
         [self dismissViewControllerAnimated:NO completion:^
         {
             switch (action)
             {
                 {case EKEventEditViewActionCanceled:
                    //NSLog(@"Canceled action");
                    break;}
    
                 {case EKEventEditViewActionSaved:
                    [self.eventStore saveEvent:thisEvent span:EKSpanThisEvent error:nil];
                    [self updateEvent:thisEvent];
                    break;}
                 {case EKEventEditViewActionDeleted:
                    [self deleteEvent:thisEvent];
                    NSError *error;
                    EKEvent *eventRemove = [self.eventStore eventWithIdentifier:thisEvent.eventIdentifier];
                    [self.eventStore removeEvent:eventRemove span:EKSpanThisEvent error:&error];
                    //NSLog(@"Deleted action");
                    break;}
                 {default:
                    break;}
             }
         }];
    }
    
    - (void)eventViewController:(EKEventViewController *)controller didCompleteWithAction:(EKEventViewAction)action
    {
    
    }