自定义 UINavigationBar 外观以在 CNContactPickerViewController 中显示

Posted

技术标签:

【中文标题】自定义 UINavigationBar 外观以在 CNContactPickerViewController 中显示【英文标题】:customize UINavigationBar appearance for showing in CNContactPickerViewController 【发布时间】:2016-07-10 12:05:11 【问题描述】:

我使用下面的代码来自定义 UINavigationBar 的外观,以便它显示 ContactPickerViewController

 id specialNavBarAppearance = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[CNContactPickerViewController class]]];

    [specialNavBarAppearance setBarTintColor:[UIColor colorWithRed:213/255.0f green:38/255.0f blue:46/255.0f alpha:1.0]];
    [specialNavBarAppearance setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                           [UIColor whiteColor], NSForegroundColorAttributeName,nil]];
    [specialNavBarAppearance setTintColor:[UIColor whiteColor]];

但没有出现任何变化。我错在哪里?

【问题讨论】:

您能先确定specialNavBarAppearance 不为零吗? 勾选,它不是零 【参考方案1】:

我为UIViewController 创建了一个类别,以便仅当您使用Method swizzling 呈现CNContactPickerViewController 时自定义UINavigationBar 的外观。在呈现之前,我检查呈现的是不是CNContactPickerViewController,然后我们改变外观。然后在解雇时,我将外观重置为默认值。它的疯狂解决方案,但它完成了工作。

#import "UIViewController+CustomAppearance.h"
#import <objc/runtime.h>
@import ContactsUI;

@implementation UIViewController (CustomAppearance)

+ (void)load 
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
    Class class = [self class];

    SEL originalSelector = @selector(presentViewController:animated:completion:);
    SEL swizzledSelector = @selector(presentViewController2:animated:completion:);

    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

    BOOL didAddMethod =
    class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));

    if (didAddMethod) 
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
     else 
        method_exchangeImplementations(originalMethod, swizzledMethod);
    



    SEL originalSelector2 = @selector(dismissViewControllerAnimated:completion:);
    SEL swizzledSelector2 = @selector(dismissViewControllerAnimated2:completion:);

    Method originalMethod2 = class_getInstanceMethod(class, originalSelector2);
    Method swizzledMethod2 = class_getInstanceMethod(class, swizzledSelector2);

    BOOL didAddMethod2 =
    class_addMethod(class,
                    originalSelector2,
                    method_getImplementation(swizzledMethod2),
                    method_getTypeEncoding(swizzledMethod2));

    if (didAddMethod2) 
        class_replaceMethod(class,
                            swizzledSelector2,
                            method_getImplementation(originalMethod2),
                            method_getTypeEncoding(originalMethod2));
     else 
        method_exchangeImplementations(originalMethod2, swizzledMethod2);
    

);


#pragma mark - Method Swizzling

- (void)dismissViewControllerAnimated2:(BOOL)flag completion:(void (^)(void))completion

   [self setupDefualtAppearance];

   [self dismissViewControllerAnimated2:flag completion:completion];




 - (void)presentViewController2:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion 

  if ([viewControllerToPresent isKindOfClass:[CNContactPickerViewController class]]) 
    [self setupContactsPickerAppearance];

 
    [self presentViewController2:viewControllerToPresent animated:flag completion:completion];
 


 - (void)setupDefualtAppearance

    id specialNavBarAppearance = [UINavigationBar appearance];

    [specialNavBarAppearance setBarTintColor:nil];
    [specialNavBarAppearance setTitleTextAttributes: nil];
    [specialNavBarAppearance setTintColor:nil];
  


  - (void)setupContactsPickerAppearance
     id specialNavBarAppearance = [UINavigationBar appearance];

     [specialNavBarAppearance setBarTintColor:[UIColor colorWithRed:213/255.0f green:38/255.0f blue:46/255.0f alpha:1.0]];
     [specialNavBarAppearance setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                  [UIColor whiteColor], NSForegroundColorAttributeName,nil]];
     [specialNavBarAppearance setTintColor:[UIColor whiteColor]];
   

   @end

【讨论】:

【参考方案2】:

UINavigationBar 始终位于UINavigationController 中。你不应该使用UINavigationController appearance 来控制它。

【讨论】:

那么我们如何自定义它在特定视图控制器(如 CNContactPickerViewController)中的外观

以上是关于自定义 UINavigationBar 外观以在 CNContactPickerViewController 中显示的主要内容,如果未能解决你的问题,请参考以下文章

删除 MFMailComposer 和 MFMessageComposer 的自定义 UINavigationBar

UINavigationBar 和新的 iOS 5+ 外观 API - 如何提供两个背景图像?

ABPeoplePicker:重置自定义导航栏外观

Angular 材料 11:具有外观轮廓的 mat-form-field 以在整个项目中具有自定义的边界半径

与自定义视图控制器一起使用时,UINavigationBar 的 UIAppearance 不起作用...?

自定义 UINavigationBar 的最惯用的 iOS5 方式?