I am trying to implement UIKeyCommand shortcuts in my app, and for the most part, it seems to work fine. Except when I present CNContactViewController in a modal view, where it seems to do something strange: after the CNContactViewController is dismissed, the keyboard shortcuts still show in the discoverability HUD but stop working throughout the app, even if the presenting view controller manually calls becomeFirstResponder
after the CNContactViewController was dismissed.
This is from FirstViewController:
- (void) showCNContacts {
CNContact * contact = [[CNContact alloc] init];
CNContactViewController *createContact = [CNContactViewController viewControllerForNewContact: contact];
createContact.delegate = self;
createContact.allowsActions = NO;
CNContactStore *store = [[CNContactStore alloc] init];
createContact.contactStore = store;
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:createContact];
navigation.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentViewController: navigation animated:YES completion: ^{
NSLog(@"presented CNContactVC - responder = %@", [[[UIApplication sharedApplication] keyWindow] performSelector:@selector(firstResponder)]);
}];
}
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact {
[viewController dismissViewControllerAnimated:YES completion:^{
[self becomeFirstResponder];
NSLog(@"after dismissing CNContactVC - responder = %@", [[[UIApplication sharedApplication] keyWindow] performSelector:@selector(firstResponder)]);
}];
}
I use the private API to see the firstResponder
, and it is correctly showing FirstViewController
as the first responder. canBecomeFirstResponder
is definitely called, so is the keyCommands
method. Holding the Command key brings up the discoverability HUD with the keyboard shortcuts showing up.
It's clearly some kind of bug with the Contacts framework. Just not sure how to work around this. Calling [self becomeFirstResponder]
inside a dispatch_async
or dispatch_after
with 1 seconds didn't work. Would love to hear some ideas.
Thanks.
The work-around I came up with was to push the CNContactViewController onto the navigation stack, instead of trying to present it modally.