设置父视图将移动的元素的accessibilityFrame

时间:2012-03-17 19:08:17

标签: ios accessibility

我有一个带有自定义标题的UITableView(即我自己创建了UIView)。我需要调整视图的一个子视图的accessibilityFrame,但我无法弄清楚如何正确设置框架的坐标 - 它们需要相对于窗口,但我不知道如何完成这一点。

我的代码看起来像

- (UIView *)tableView:(UITableView *)tableView
viewForHeaderInSection:(NSInteger) section
{
    CGRect bounds = CGRectMake(0, 0, [tableView frame].size.width, 48);
    UIView *header = [[UIView alloc] initWithFrame:bounds];

    UILabel *labelOne = [[UILabel alloc] initWithFrame:
        CGRectMake(0, 0, bounds.size.width - 80, 18)];
    UILabel *labelTwo = [[UILabel alloc] initWithFrame:
        CGRectMake(0, 20, bounds.size.width - 80, 18)];

    CGRect frameOne = [labelOne frame];
    CGRect frameTwo = [labelTwo frame];

    [labelTwo setIsAccessibilityElement:NO];
    [labelOne setAccessibilityFrame:CGRectUnion(frameOne, frameTwo)];

    // ...

    return header;
}

我有两个UILabel,我想将它合并为一个用于VoiceOver的目的。我通过忽略第二个标签并扩展第一个标签的框架以覆盖第二个标签的区域来实现这一点。 (第二个标签位于第一个标签的下方。)问题在于获取帧。如果我使用上面显示的代码,可访问性框架的大小正确,但其位置就好像UITableView的标题位于屏幕的左上角。我试着修改代码来说

CGRect frameOne = [header convertRect:[labelOne frame] toView:nil];
CGRect frameTwo = [header convertRect:[labelTwo frame] toView:nil];

但同样的事情发生了。后一段代码不应该将UILabels的帧转换为窗口相对坐标吗?

我想也许问题在于,当UIView被创建时,它不知道它将被放置在屏幕上的哪个位置(并且作为UITableView的一部分,它可以在整个地方滚动)。是否有必要将accessibilityFrame实现为每次调用时检查UIView位置的消息?

2 个答案:

答案 0 :(得分:1)

有一个辅助功能可以帮助您完成这项工作:UIAccessibilityConvertFrameToScreenCoordinates。此函数采用CGRect并将其从视图的坐标系转换为屏幕坐标。

答案 1 :(得分:0)

我认为这不是创建UIView的时间,因为我认为window应该不是 - niltableView:viewForHeaderInSection:时被调用。我认为问题是convertRect:toView:消息的接收者。不应将此消息传递给header,而应将其传递给[self view]

您正在从接收器坐标系转换为另一个视图的坐标系,在本例中为nil或应用中的UIWindow。当header收到此消息时,您正在从 header坐标系转换为window的坐标系,但header本身就是[self view]的子视图。相反,您想要[self view]进行转换,这应该考虑任何UINavigationBar等等。

CGRect frameOne = [[self view] convertRect:[labelOne frame] toView:nil];
CGRect frameTwo = [[self view] convertRect:[labelTwo frame] toView:nil];