H5 页面直接调起手机的相册和浏览功能,不通过App 开发人员,不使用JS交互。H5开发人员使用了这样一段代码,就可以直接调起相机、相册和浏览功能,相机受权限影响,而相册不受App权限的影响:
<input type=\"file\" accept=\"image/*;capture=camera\">
那么打开的页面是通过H5 打开的,页面样式与App的页面样式不统一,但是App开发者,找不到对应的控制器,也无法修改样式。
那么我们需要做的是找到对应的控制器
使用Swizzling
具体原理是给UIViewControlle创建分类UIViewController+Swizzling ,hook到-viewWillAppear: 方法,在交换的自己重写的方法中改变导航栏的样式,代码如下:
- (void)swizzlingViewWillAppear:(BOOL)animated {
[self swizzlingViewWillAppear:animated];
if ([self isMemberOfClass:NSClassFromString(@"PUPhotoPickerHostViewController")] || [self isMemberOfClass:NSClassFromString(@"UIDocumentPickerViewController")]) {
[self configureRongCloudNavigation];
}
}
+ (void)load {
[super load];
//原本的willAppear方法
Method willAppearOriginal = class_getInstanceMethod([self class], @selector(viewWillAppear:));
//用于交换的willAppear方法
Method willAppearNew = class_getInstanceMethod([self class], @selector(swizzlingViewWillAppear:));
//交换
if (!class_addMethod([self class], @selector(viewWillAppear:), method_getImplementation(willAppearNew), method_getTypeEncoding(willAppearNew))) {
method_exchangeImplementations(willAppearOriginal, willAppearNew);
}
}
- (void)configureRongCloudNavigation {
//点击系统相册弹出的控制器
if ([self isMemberOfClass:NSClassFromString(@"PUPhotoPickerHostViewController")]) {
UIBarButtonItem *barItem = [UIBarButtonItem appearance];
barItem.tintColor = [UIColor whiteColor];
UINavigationBar *navBar = [UINavigationBar appearance];
[navBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
navBar.tintColor = [UIColor whiteColor];
}
//点击浏览弹出的控制器
if ([self isMemberOfClass:NSClassFromString(@"UIDocumentPickerViewController")]) {
UIBarButtonItem *barItem = [UIBarButtonItem appearance];
barItem.tintColor = [UIColor blueColor];
UINavigationBar *navBar = [UINavigationBar appearance];
[navBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blueColor]}];
navBar.tintColor = [UIColor blueColor];
}
}
到此页面样式就修改完成了。