UISegmentedControl 辅助功能模式样式

UISegmentedControl accessibility mode styling

我正在为分段控件设置颜色,如下所示:

segmentedControl.backgroundColor = .gray
segmentedControl.selectedSegmentTintColor = .red

let textAttrs: [NSAttributedString.Key : Any] = [
    .foregroundColor: UIColor.white
]
segmentedControl.setTitleTextAttributes(textAttrs, for: .normal)

它运行良好,但是当用户长按它时(在设置中启用大字体),我得到以下信息:

如您所见,文本不可读。有什么方法可以为辅助功能视图设置 background/tint 颜色吗?

我找到的最佳解决方案是像这样为标题属性中的文本设置背景颜色:

let textAttrs: [NSAttributedString.Key : Any] = [
    .foregroundColor: UIColor.white,
    .backgroundColor: segmentedControl.backgroundColor!
]
segmentedControl.setTitleTextAttributes(textAttrs, for: .normal)

let textAttrsSelected: [NSAttributedString.Key : Any] = [
    .foregroundColor: UIColor.white,
    .backgroundColor: segmentedControl.selectedSegmentTintColor!
]
segmentedControl.setTitleTextAttributes(textAttrsSelected, for: .selected)

结果更好了(至少文本是可读的),但仍然看起来不太好:

理想情况下,我希望辅助模式视图的所选项目具有与主视图中相同的背景颜色和色调。

似乎没有任何 public API 可以帮助您解决这个问题。您应该向 Apple 提出反馈请求。

与此同时,如果您对有些棘手的解决方法感兴趣,可以覆盖控制器的 presentViewController:animated:completion: 并稍微“触摸”视图层次结构。

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    NSString* controllerClassName = NSStringFromClass(viewControllerToPresent.class);
    
    if([controllerClassName hasPrefix:@"UIAccessibility"] && [controllerClassName containsString:@"Segmented"])
    {
        [[viewControllerToPresent valueForKey:@"segmentButtons"] enumerateObjectsUsingBlock:^(UIButton* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [obj setValue:nil forKeyPath:@"segment.appearanceStorage"];
        }];
    }
    
    [super presentViewController:viewControllerToPresent animated:flag completion:completion];
}

如果您没有自定义分段控件,这将使弹出窗口按原样显示:

如您所见,那里有一些私人 API 用法,因此您需要将其隐藏。

如果您想要自定义弹出框使其看起来像您的分段控件,这将更加困难。白色选择矩形是一个图像,所以你需要修改它,但也要考虑改变外观(light/dark 模式):

我建议不要走那条路。默认外观弹出窗口应该足够好。