网络知识 娱乐 [iOS] 如何创建自定义工具栏覆盖默认NavigationBar并调整其VoiceOver的阅读顺序

[iOS] 如何创建自定义工具栏覆盖默认NavigationBar并调整其VoiceOver的阅读顺序

项目场景

iOS开发过程中,我们有时候需要根据需求自定义创建顶部的工具栏,以代替系统默认的NavigationBar。本文主要分享如何创建该自定义工具栏,从而覆盖系统默认的NavigationBar,同时分享如何解决VoiceOver阅读顺序不对的问题。


解决方案

创建自定义工具栏

新建一个 UIView 对象作为自定义工具栏的主要视图,并添加必要的按钮,最后将其加入到NavigationControllerview中。代码如下:

@interface ViewController ()

@property (strong, nonatomic) UIView *customNavigationBar;

@end

@implementation ViewController

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [self setupCustomNavigationBar];
}

- (void)setupCustomNavigationBar {
    self.customNavigationBar = [UIView new];
    self.customNavigationBar.backgroundColor = UIColor.redColor;
    self.customNavigationBar.frame = self.navigationController.navigationBar.frame;
    [self.navigationController.view addSubview:self.customNavigationBar];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.frame = CGRectMake(0, 0, 60, 44);
    button.tintColor = UIColor.whiteColor;
    [button setTitle:@"Back" forState:UIControlStateNormal];
    [self.customNavigationBar addSubview:button];
}

@end

更新工具栏大小和位置

如果我们用frame属性对customNavigationBar进行布局时,需要在屏幕旋转或者视图重布局时将其重新定位,代码如下:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        self.customNavigationBar.frame = self.navigationController.navigationBar.frame;
    } completion:nil];
}

-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.customNavigationBar.frame = self.navigationController.navigationBar.frame;
}

调整VoiceOver的阅读顺序

通过上述代码,我们再添加一个UITableView和底部两个UIButton得到最终的界面如下:
图片还在路上,稍等...

当我们开启Accessibility Inspector测试VoiceOver时,你会发现它的阅读顺序是:

  1. UITableView中的所有单元(如上图绿色覆盖区域所示)
  2. 底部的按钮
  3. CustomNavigationBar内的所有按钮

因此,当我们添加自定义的工具栏到NavigationControllerview中时,VoiceOver将默认最后阅读工具栏里面的控件,但在实际应用中我们需要优先阅读它们。因此我们需要调整navigationController.viewaccessibilityElements如下:

- (void)setupCustomNavigationBar {
    ......

    self.navigationController.view.accessibilityElements = 
    @[self.customNavigationBar, self.tableView, self.bottomButton];
}