I am working on an application that presents some data in detailViewController. I have a rightBarButton in a navbar that represents a UIActivityViewController that is populated with my own UIActivity sublclassed elements. Most of them work fine, as they simply change the small aspect to the data from the detailed view, but I need one of them to open the modalViewController when it is selected. I keep getting the following warning from the console.
Warning: Attempt to present <UINavigationController: 0x1fd00590> on <UITabBarController: 0x1fde1070> which is already presenting <MPActivityViewController: 0x1fd2f970>
I believe it is worth noting that the application does not crash, but the modal view is also not displayed. I assume that the UIActivityViewController is a modal view, and you can only display one at a time, so the task is to figure out how to execute my session after the ActivityView disappears, but this is where I am at a dead end. I welcome any help, thoughts or feedback. I tried Google, but I was not lucky, I suppose, because the UIActivityViewController is so new.
Here is my setup so far, my UIActivity objects have a delegate set in the detailViewController for a user protocol that allows the detailViewController to make data changes and then update their presentation.
for the actions in question that the modalView controller should represent, I tried several approaches that get the same warning.
None of these works !!!
1) just tried executing segue from my delegate method
- (void) activityDidRequestTransactionEdit { NSLog(@"activityDidRequestTransactionEdit"); [self performSegueWithIdentifier:@"editTransaction" sender:self]; }
2) I tried to set the completion block in the UIActivityViewController and so my delegate method set the bool flag, which should show a modal view (self.editor)
[activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) { NSLog(@"completed dialog - activity: %@ - finished flag: %d", activityType, completed); if (completed && self.editor) { [self performSegueWithIdentifier:@"editTransaction" sender:self]; } }];
3) by subclassing the UIActivityViewController interface itself, providing it with a detailView as a delegate and overriding it. rejectControllerAnimated: method with my own termination block
- (void) dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion { [super dismissViewControllerAnimated:flag completion:^{ [self.MPActivityDelegate activityDidRequestTransactionEdit]; }]; }
Working solution
In the UIActivity subclass, you need to override this method as follows
- (UIViewController *) activityViewController { MPEditMyDataViewController *controller = [[MPEditMyDataViewController alloc] init]; controller.activity = self;
in your MPEditMyDataViewController.h (view controller that should select the selected action) you need the property back to the activity subclass so
@property (strong, nonatomic) MPEditMyDataActivity *activity;
in your MPEditMyDataViewController.m
- (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; self.navigationItem.leftBarButtonItem = cancelButton; }