CNContactViewController隐藏导航栏

5
当我将CNContactViewController推到UITableViewController子类的堆栈上,该子类处于UINavigationController中时,顶部导航栏几乎完全隐藏。但亮度调到最高后,你可以看到后退箭头后面跟着“Detail”一词和系统状态栏。当我点击屏幕的那个角落时,确实会关闭CNContactViewController

enter image description here

当然,这并不好,因为用户可能甚至看不到导航栏的文本,也不知道如何按任何按钮来关闭它。
有没有办法使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以下的版本中没有。当我点击“添加到现有联系人”时,我也能够获得正确着色的导航栏,但当该视图控制器被关闭时,它又会出现问题。

enter image description here

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

2
您的第二个屏幕截图显示了这个问题的原因:您已将栏(或一般的栏按钮项)的色调设置为白色。因此,在联系人视图控制器中,它们是白色的,并且在透明导航栏和白色背景前也是白色的。
您无法直接改变栏的色调颜色,但可以通过以下两种方式解决此问题:
1. 使您的导航栏不透明。在这种情况下,联系人视图控制器的导航栏将是黑色的,您的白色栏按钮项将可见。 2. 另一种方法是在推送联系人视图控制器时更改导航栏的色调颜色(而不是栏色调颜色,而是向其栏按钮项传达的色调颜色),并在弹出时将其改回。
编辑:好吧,我看到还有一个进一步的问题,因为新联系人视图控制器是在您的前面呈现的另一个视图控制器。如果您不想放弃白色栏按钮项设置,那么您必须使用外观代理来在推送联系人视图控制器时将UIBarButtonItem的色调颜色设置为其他颜色,然后当您的导航控制器委托告诉您用户正在弹回到您的视图控制器时,将其重置回白色。

1
谢谢你的建议。我对CNContactViewController进行了子类化,并在viewWillAppearviewDidAppear中重写了导航栏的颜色,并将其推到了一个该类的实例中。现在我可以看到文字了。但是当我点击“创建新联系人”时,我遇到了类似的问题。在这个假定的导航栏中,我看不到按钮的文字,但当我点击屏幕的左右角时,会触发"Cancel"和"Save"的行为。奇怪的是,当点击“添加到现有联系人”时,我没有任何问题,你可以在我的原始问题中看到。有什么想法吗? - user6168494
我认为我的原始想法很好。请注意,未知联系人视图控制器一直存在缺陷;在iOS 9中,您根本不能使用它(它会破坏界面),正如我在这里所讨论的:https://dev59.com/I1wY5IYBdhLWcg3wH01C - matt
谢谢分享这个链接。你最初的想法是什么?当我尝试您的第一个建议时,我确实看到导航栏变为黑色,白色文本在其上,但下一个屏幕(当我点击“创建新联系人”时)没有发生这种情况。当我采用自己的解决方案时,它与你的第二个建议相似(我认为是吧?),我仍然看不到“创建新联系人”屏幕上的文本。我不知道点击该按钮时显示哪个视图控制器类,因此我不知道要重写哪个类,就像我为CNContactViewController那样。 - user6168494
1
是的,我是正确的。您可以使用外观代理将UIBarButtonItem的色调颜色更改为一些深色,例如蓝色,当您推送联系人视图控制器时,并在视图控制器弹回到您的视图控制器时将其改回白色。 - matt
感谢您的编辑,对于未来的观众,@matt。这就是我在您编辑前几分钟通过一些试错找出来的。 - user6168494
2
请注意,我并不是在说这些都是好的。它们并不好。将这些视图控制器作为进程外接口注入到您的界面上的整个概念是可怕的。您应该向苹果(bugreport.apple.com)提交错误报告。您不应该需要绕着月球跳舞才能控制此界面。毕竟,这是_您的_应用程序,而不是苹果的! - matt

2
我花了数小时与CNContactViewController纠缠,试图强制其适应我的UINavigation外观设置,但它却不行。它有自己的外观和感觉。我查看了像Mail和Notes这样的iOS应用程序,以查看它们如何显示CNContactViewController,似乎是显示为一个弹出窗口,所以我也走了这条路线。
即使如此也并不容易。CNContactViewController必须包装在UINavigationView中,以便Create New Contact和其他视图可以推动。如果您覆盖了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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接