CNContactViewController 隐藏导航栏

CNContactViewController hiding navigation bar

当我将 CNContactViewController 推入 UINavigationController 内的 UITableViewController 子类的堆栈时,顶部导航栏几乎完全隐藏。但是随着亮度一直调高,您可以看到后退箭头后面跟着单词 "Detail",以及系统状态栏。当我点击屏幕的那个角落时,CNContactViewController 确实被关闭了。

当然这不好,因为用户可能甚至看不到导航栏的文本而现在按任何按钮将其关闭。

有什么方法可以使 CNContactViewController 的导航栏色调与显示它的视图控制器(我的应用程序的其余部分)相同?

CNContactViewController *controller = [CNContactViewController viewControllerForUnknownContact:person];

controller.contactStore = [[CNContactStore alloc] init];
controller.delegate = self;
controller.allowsActions = NO;

[self.navigationController pushViewController:controller animated:YES];

我应该注意,我只在 iOS 10 上遇到这个问题,而不是低于 10 的版本。当我点击 "Add to Existing Contact" 时,我也确实得到了正确着色的导航栏,但是它当该视图控制器被关闭时再次中断。

所以,我的问题是:有什么方法可以使 CNContactViewController 的导航栏色调与显示它的视图控制器(我的应用程序的其余部分)相同?

您的第二个屏幕截图显示了此问题的原因:您已将栏(或一般的栏按钮项目)的色调设置为白色。因此,它们在透明导航栏前为白色,在联系人视图控制器中为白色背景。

您不能直接对 bar 色调做任何事情,但您可以通过以下两种方式之一解决此问题:

  • 一个是让你的导航栏不透明。在这种情况下,联系人视图控制器的导航栏将是黑色的,而您的白色栏按钮项目将是可见的。

  • 另一种方法是在接触视图控制器按下时更改导航栏的色调(不是栏色调,而是它传达给其栏按钮项目的色调),并更改当它弹出时它会回来。

编辑 好的,我发现还有一个问题,因为新联系人视图控制器是呈现在您面前的另一个视图控制器。如果你拒绝放弃你的白色条形按钮项目设置,你将不得不使用外观代理在你按下接触视图控制器时将 UIBarButtonItem 色调颜色设置为其他颜色,然后在你的导航控制器时将其重置回你的白色委托告诉您用户正在弹出回到您的视图控制器。

我花了几个小时研究 CNContactViewController 试图强制它适应我的 UINavigation 外观设置,但它就是不会。它有自己的外观和感觉。我查看了 iOS 应用程序,例如 Mail 和 Notes,看看它们如何显示 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];
}