简体   繁体   English

CNContactViewController隐藏导航栏

[英]CNContactViewController hiding navigation bar

When I push a CNContactViewController on to the stack of UITableViewController subclass which is within a UINavigationController , the top navigation bar is almost entirely hidden. 当我将CNContactViewControllerCNContactViewController UINavigationController内的UITableViewController子类的堆栈时,顶部导航栏几乎完全隐藏。 But with the brightness all the way up, you make out the back arrow followed by the word "Detail", and the system status bar. 但是随着亮度一直向上,你会看到后面的箭头,然后是“细节”和系统状态栏。 When I tap that corner of the screen, the CNContactViewController is indeed dismissed. 当我点击屏幕的那个角落时,CNContactViewController确实被解雇了。

在此输入图像描述

Of course this is not good, since a user would probably not even see the text of the navigation bar and now to press any buttons to dismiss. 当然这不好,因为用户可能甚至看不到导航栏的文本,现在按任何按钮来解除。

Is there any way to make the navigation bar tint of the CNContactViewController be the same as the view controller that showed it (the rest of my app)? 有没有办法让CNContactViewController的导航栏色调与显示它的视图控制器(我的应用程序的其余部分)相同?

CNContactViewController *controller = [CNContactViewController viewControllerForUnknownContact:person];

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

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

I should note that I'm only experiencing this problem on iOS 10, and not versions below 10. I also do get the properly tinted navigation bar when I tap "Add to Existing Contact", but it breaks again when that view controller is dismissed. 我应该注意到我只是在iOS 10上遇到这个问题,而不是10以下的版本。当我点击“添加到现有联系人”时,我也得到了正确着色的导航栏,但是当该视图控制器被解除时它再次中断。

在此输入图像描述

So again, my question is: Is there any way to make the navigation bar tint of the CNContactViewController be the same as the view controller that showed it (the rest of my app)? 所以再一次,我的问题是: 有没有办法让CNContactViewController的导航栏色调与显示它的视图控制器(我的应用程序的其余部分)相同?

Your second screen shot shows the reason for this problem: you have set the tint color for your bar (or bar button items in general) to be white. 您的第二个屏幕截图显示了此问题的原因:您已将条形(或一般条形按钮项目)的色调颜色设置为白色。 Hence, they are white in front of the transparent navigation bar and white background in the contact view controller. 因此,它们在透明导航条前面是白色的,在接触视图控制器中是白色背景。

You can't do anything directly about the bar tint color, but you can solve this in either of two ways: 您无法直接对条形色调进行任何操作,但您可以通过以下两种方式之一解决此问题:

  • One is to make your navigation bar nontranslucent. 一个是让你的导航栏不透明。 In that case, the contact view controller's navigation bar will be black, and your white bar button items will be visible. 在这种情况下,联系人视图控制器的导航栏将为黑色,并且您的白色条按钮项将可见。

  • Another approach is to change your navigation bar's tint color (not the bar tint color, but the tint color that it communicates down to its bar button items) as the contact view controller pushes, and change it back when it pops. 另一种方法是在联系人视图控制器按下时更改导航栏的色调颜色(不是条纹色调,而是它向下传递到其按钮项目的色调颜色),并在弹出时更改它。

EDIT Okay, I see that there's a further problem because the New Contact view controller is a further view controller presented in front of yours. 编辑好的,我看到还有一个问题,因为New Contact视图控制器是在你面前呈现的另一个视图控制器。 If you refuse to give up your white bar button item setting, you will have to use the appearance proxy to set the UIBarButtonItem tint color to something else when your push the contact view controller, and then reset it back to your white when your navigation controller delegate tells you that the user is popping back to your view controller. 如果您拒绝放弃白条按钮项目设置,则在推动联系人视图控制器时,必须使用外观代理将UIBarButtonItem色调设置为其他颜色,然后在导航控制器时将其重置为白色delegate告诉您用户正在弹回您的视图控制器。

I spent hours wrestling with CNContactViewController trying to force it to fit into my UINavigation appearance settings, but it just won't. 我花了几个小时与CNContactViewController进行摔跤,试图强制它适合我的UINavigation外观设置,但它不会。 It has it's own look and feel. 它有自己的外观和感觉。 I had a look at iOS apps like Mail and Notes to see how they show the CNContactViewController and it seems to be shown as a popover, so I went that way too. 我看了一下iOS应用程序,比如Mail和Notes,看看它们是如何显示CNContactViewController的,它似乎显示为一个popover,所以我也是这样。

Even that isn't trivial. 即使这不是微不足道的。 The CNContactViewController has to be wrapped in a UINavigationView so that the Create New Contact and other views can push. CNContactViewController必须包装在UINavigationView中,以便Create New Contact和其他视图可以推送。 And if you have overridden the UINavigationBar appearance defaults, you need to set them back to standard before and after. 如果您已覆盖UINavigationBar外观默认值,则需要在之前和之后将它们设置回标准。 Here's how it looks in the end: 以下是它最终的表现:

@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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM