如何创建与视图边界不同的accessibilityFrame?

时间:2013-02-22 21:59:26

标签: ios accessibility voiceover

我实际上知道如何做到这一点,但我这样做的方式让我想到了两个真正的问题。首先,我在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);
}

1 个答案:

答案 0 :(得分:8)

辅助功能框架在屏幕坐标(see documentation)中指定。

转换

-[UIView convertRect:toView:] 
如果toView为nil,则

将视图坐标转换为窗口坐标。

要100%正确,使用

进行从窗口到屏幕坐标的额外转换
-[UIWindow convertPoint:toWindow:] 

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

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

在你制作巨大的辅助功能框架之前要考虑的一件事:如果你有非常小的按钮,它们也可能很难被普通用户击中。考虑将它们(或至少是它们对触摸做出响应的区域)做大。 Apple recommends至少44 x 44点。