CNContactViewController 隐藏导航栏

Posted

技术标签:

【中文标题】CNContactViewController 隐藏导航栏【英文标题】:CNContactViewController hiding navigation bar 【发布时间】:2016-11-15 01:23:05 【问题描述】:

当我将CNContactViewController 推送到UITableViewController 子类的堆栈中时,该堆栈位于UINavigationController 中,顶部导航栏几乎完全隐藏。但是随着亮度一路上升,您可以看到后面的箭头,后面跟着“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 的版本。当我点击“添加到现有联系人”时,我也确实得到了正确着色的导航栏,但是当该视图再次中断时控制器被解雇。

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

【问题讨论】:

【参考方案1】:

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

您无法直接对 条形 色调颜色执行任何操作,但您可以通过以下两种方式之一解决此问题:

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

另一种方法是在联系人视图控制器按下时更改导航栏的色调颜色(不是栏色调颜色,而是向下传达给其栏按钮项的色调颜色),并在它按下时将其更改回来啪啪啪。

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

【讨论】:

感谢您的建议。我将CNContactViewController 子类化并覆盖viewWillAppearviewDidAppear 中的导航栏颜色并推送到此类的一个实例。我现在可以看到文字了。但是现在当我点击“创建新联系人”时我遇到了类似的问题。我在这个假定的导航栏中看不到按钮的文本,但是当我点击屏幕的左右角时会观察到“取消”和“保存”行为。奇怪的是,点击“添加到现有联系人”时我没有任何问题,正如您在我原来的问题中看到的那样。有什么想法吗? 我觉得我最初的想法很不错。 — 请注意,Unknown Contact 视图控制器一直存在问题;在 iOS 9 中你根本无法使用它(它只是破坏了界面),正如我在这里讨论的那样:***.com/questions/32973254/… 感谢分享该链接。你最初的想法是什么?当我尝试您的第一个项目符号建议时,我确实看到导航栏变黑并带有白色文本,但是当我点击 创建新联系人 时,下一个屏幕不会发生这种情况。当我采用自己的解决方案时,这与您的第二个项目符号建议(我认为?)相同,我仍然看不到 创建新联系人 屏幕的文本。我不知道点击所述按钮时会出现什么类的视图控制器,所以我不知道要以与CNContactViewController 相同的方式覆盖哪个类。 是的,我是对的。您可以使用外观代理在推送联系人视图控制器时将 UIBarButtonItem 的色调更改为某种深色,例如蓝色,并在视图控制器弹回视图控制器时将其更改回白色。 @dtorreci4ejg 请注意,我并不是说这些都是好的。它不是。将这些视图控制器作为进程外接口“注入”到您的界面之上的整个概念是残酷的。您确实应该向 Apple (bugreport.apple.com) 提交错误报告。你不必为了控制这个界面而绕着月亮跳舞。毕竟,它是您的应用,而不是 Apple 的!【参考方案2】:

我花了几个小时与 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];

【讨论】:

以上是关于CNContactViewController 隐藏导航栏的主要内容,如果未能解决你的问题,请参考以下文章

无法编辑或关闭 CNContactViewController (iOS)

CNContactViewController 导航栏背景颜色与我的应用不匹配

CNContactViewController 对响应者链做了一些奇怪的事情

IOS Swift CNContactViewController 导航栏不显示 UINavigation 控制器

CNUI ERROR 联系人视图延迟出现超时

从原生控制器返回 Flutter 应用