7

我实际上知道如何做到这一点,但我这样做的方式让我想到了两个真正的问题。首先,我在 UIButton 子类中更改此框架,如下所示:

- (CGRect)accessibilityFrame {
    CGRect rect = [self.superview convertRect:self.frame toView:nil];
    rect.size.width *= 5;
    return rect;
}

如果我省略了这个方法的第一行,那么这个按钮的可访问性框架会出现在屏幕的绝对左上角,而不管它的原始位置。我发现用于覆盖可访问性框架的所有代码示例都使用了坐标转换的一些变体,但我完全不明白为什么。为什么不能在与视图框架相同的坐标系中处理此属性,因为这会使修改可访问性框架变得非常简单?

我的第二个问题与打开 VoiceOver 的情况下这个可访问性框架的实际功能有关。当我以这种方式修改可访问性框架时,焦点矩形会按预期变大。不幸的是,这种效果似乎纯粹是装饰性的。即使焦点矩形现在比按钮本身大得多,我仍然只能通过在按钮边界内正确点击来将焦点应用于按钮;如果我在焦点矩形内部但在按钮本身之外点击,则不会发生任何事情。这对我来说是个大问题,因为我正在尝试扩展一些控件的“虚拟”大小,这些控件非常小,除非你能看到它们,否则它们很难实际点击。如果视力受损的用户可以,我根本不理解让焦点矩形在外观上更大的意义

编辑:添加这个位就可以了:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint newPoint = [self.superview convertPoint:point toView:nil];
    return CGRectContainsPoint(self.accessibilityFrame, newPoint);
}

我仍然很想知道为什么这样的事情甚至是必要的。

编辑 2:上面的代码仅在特殊情况下有效(在多个嵌套子视图内)。更通用的解决方案是:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint newPoint = [self convertPoint:point toView:nil];
    return CGRectContainsPoint(self.accessibilityFrame, newPoint);
}
4

1 回答 1

8

可访问性框架在屏幕坐标中指定(参见文档)。

转换

-[UIView convertRect:toView:] 

如果 toView 为 nil,则将视图坐标转换为窗口坐标。

为了 100% 正确,从窗口到屏幕坐标的额外转换使用

-[UIWindow convertPoint:toWindow:] 

(再次,使用 nil toWindow)将是必需的。

现在,您可能已经知道需要在 VoiceOver 光标内双击才能触发按钮的操作。默认情况下,双击会点击辅助框架的中心。但是,如果您修改的辅助功能框架的中心不在您的按钮上,则不会发生任何事情。方便的是,该accessibilityActivationPoint方法允许您将该中心放在其他地方(例如,就在按钮的实际中心上)。同样,不要忘记转换为屏幕坐标。

在你开始制作巨大的辅助框架之前要考虑的一件事:如果你有非常小的按钮,普通用户也可能很难点击它们。考虑使它们(或至少它们响应触摸的区域)更大。Apple 建议至少 44 x 44 点。

于 2013-02-22T23:50:06.933 回答