我花了几个小时与 CNContactViewController 搏斗,试图强制它适应我的 UINavigation 外观设置,但它不会。它有自己的外观和感觉。我查看了 Mail 和 Notes 等 iOS 应用程序,看看它们如何显示 CNContactViewController 并且它似乎显示为弹出框,所以我也这样做了。
即使这也不是微不足道的。CNContactViewController 必须包装在 UINavigationView 中,以便创建新联系人和其他视图可以推送。如果您覆盖了 UINavigationBar 外观默认值,则需要在前后将它们设置回标准。这是它最终的样子:
@property (strong, nonatomic) CNContactViewController *contactViewController;
@property (assign, nonatomic) UIBarStyle saveAppearanceBarStyle;
@property (strong, nonatomic) UIColor *saveAppearanceBarTintColor;
@property (strong, nonatomic) UIColor *saveAppearanceTintColor;
@property (strong, nonatomic) UIColor *saveAppearanceBackgroundColor;
@property (strong, nonatomic) NSDictionary<NSAttributedStringKey, id> * saveAppearanceTitleTextAttributes;
@property (assign, nonatomic) BOOL saveAppearanceTranslucent;
- (IBAction)onAddToContactsButtonTapped:(id)sender
self.contactViewController = [CNContactViewController viewControllerForUnknownContact: ... ]; // as before
[self suspendNavBarAppearanceSettings];
UINavigationController *popNav = [[UINavigationController alloc] initWithRootViewController:self.contactViewController];
popNav.modalPresentationStyle = UIModalPresentationPopover;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(onAddToContactsDoneTapped:)];
self.contactViewController.navigationItem.leftBarButtonItem = doneButton;
[self presentViewController:popNav animated:YES completion:nil];
UIPopoverPresentationController *popoverController = newNav.popoverPresentationController;
popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny;
popoverController.sourceRect = ...; // where you want it to point
popoverController.sourceView = ...; // where you want it to point
popoverController.delegate = self;
}
- (void) suspendNavBarAppearanceSettings
{
self.saveAppearanceBarStyle = [UINavigationBar appearance].barStyle;
self.saveAppearanceBarTintColor = [UINavigationBar appearance].barTintColor;
self.saveAppearanceTintColor = [UINavigationBar appearance].tintColor;
self.saveAppearanceBackgroundColor = [UINavigationBar appearance].backgroundColor;
self.saveAppearanceTitleTextAttributes = [UINavigationBar appearance].titleTextAttributes;
self.saveAppearanceTranslucent = [UINavigationBar appearance].translucent;
[UINavigationBar appearance].barStyle = UIBarStyleDefault;
[UINavigationBar appearance].barTintColor = nil;
[UINavigationBar appearance].tintColor = nil;
[UINavigationBar appearance].backgroundColor = nil;
[UINavigationBar appearance].titleTextAttributes = nil;
[UINavigationBar appearance].translucent = YES;
}
- (void) restoreNavBarAppearanceSettings
{
[UINavigationBar appearance].barStyle = self.saveAppearanceBarStyle;
[UINavigationBar appearance].barTintColor = self.saveAppearanceBarTintColor;
[UINavigationBar appearance].tintColor = self.saveAppearanceTintColor;
[UINavigationBar appearance].backgroundColor = self.saveAppearanceBackgroundColor;
[UINavigationBar appearance].titleTextAttributes = self.saveAppearanceTitleTextAttributes;
[UINavigationBar appearance].translucent = self.saveAppearanceTranslucent;
}
- (void)onAddToContactsDoneTapped:(id)sender
{
[self restoreNavBarAppearanceSettings];
[[self presentedViewController] dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - CNContactViewControllerDelegate
- (void)contactViewController:(CNContactViewController *)viewController
didCompleteWithContact:(nullable CNContact *)contact
{
[self restoreNavBarAppearanceSettings];
[[self presentedViewController] dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
// This method is only called if we are presented in a popover, i.e. on iPad
// as opposed to full screen like on a phone.
// on iPad you just tap outside to finish, so remove the Done button
self.contactViewController.navigationItem.leftBarButtonItem = nil;
}
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController
{
[self restoreNavBarAppearanceSettings];
}