2011-05-03 6 views
3

UITableViewCell 안에 사용자 정의보기를 넣으려고합니다. 물론 UITableView 내에 있습니다. 이 사용자 정의보기를 액세스 가능하게 만들고 싶습니다. UIAccessibilityContainer (자체 UIView로 구현되지 않은 몇 가지 시각적 요소가 포함되어 있으므로)을 만들어야합니다.테이블보기의 UIAccessibilityContainer

이렇게하면 테이블이 스크롤 될 때마다 요소의 위치가 엉망이됩니다. VoiceOver를 사용하여 요소를 페이징하는 동안 선택한 요소를 화면 중앙에 놓기 위해 테이블을 자동으로 스크롤하지만, VoiceOver가 요소가 더 이상 시각적으로 어디에 있지 않다고 생각하는지에 대한 개요를 표시합니다. 그것은 자동 스크롤하기 전에이 행 사가 어디 될 일이 있기 때문에 관리자는 말한다 스크린 샷

broken

주 "행 4 요소 (2)"만 강조 표시된 지역은 행 7의 어떤 임의의 장소입니다 탁자. '

나의 생각은 내가 테이블 뷰 스크롤,하지만 난이 UIAccessibilityContainer를 사용하지 않는 경우 그렇게 할 필요가 없습니다 때 레이아웃 변경을 게시 할 UIAccessibilityPostNotification()을 사용해야 할 수도 있다는 것입니다 내가 shouldn처럼 느낀다 t는 그것을해야하고 시스템이 나를 위해 이것을 처리해야한다는 것을 의미합니다. 그러나 UIAccessibilityElement이 화면 좌표로 설정된 accessibilityFrame을 가질 필요가 있다는 사실은 사물에 주름을 던진 것처럼 보입니다. (보너스 질문 : 왜 그런 식의 API가 디자인 되었습니까? 요소의 컨테이너 또는 그와 유사한 프레임과 관련하여 프레임을 정의하는 이유는 무엇입니까? Arg)

다음과 같은 경우에 사용자 정의보기의 구현이 있습니다. 문제를 일으킨다. 전체 프로젝트 (Xcode 4)의 경우 click here.

@implementation CellView 
@synthesize row=_row; 

- (void)dealloc 
{ 
    [_accessibleElements release]; 
    [super dealloc]; 
} 

- (void)setRow:(NSInteger)newRow 
{ 
    _row = newRow; 

    [_accessibleElements release]; 
    _accessibleElements = [[NSMutableArray arrayWithCapacity:0] retain]; 

    for (NSInteger i=0; i<=_row; i++) { 
     UIAccessibilityElement *element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self]; 
     element.accessibilityValue = [NSString stringWithFormat:@"Row %d, element %d", _row, i]; 
     [_accessibleElements addObject:element]; 
     [element release]; 
    }  

    [self setNeedsDisplay]; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    [[UIColor lightGrayColor] setFill]; 
    UIRectFill(self.bounds); 

    [[UIColor blackColor] setFill]; 
    NSString *info = [NSString stringWithFormat:@"Row: %d", _row]; 
    [info drawAtPoint:CGPointZero withFont:[UIFont systemFontOfSize:12]]; 

    [[[UIColor whiteColor] colorWithAlphaComponent:0.5] setFill]; 
    NSInteger x=0, y=0; 
    for (NSInteger i=0; i<=_row; i++) { 
     CGRect rect = CGRectMake(12+x, 22+y, 30, 30); 

     UIAccessibilityElement *element = [_accessibleElements objectAtIndex:i]; 
     element.accessibilityFrame = [self.window convertRect:[self convertRect:rect toView:self.window] toWindow:nil]; 

     UIRectFill(rect); 
     x += 44; 

     if (x >= 300) { 
      x = 0; 
      y += 37; 
     } 
    } 
} 

- (BOOL)isAccessibilityElement 
{ 
    return NO; 
} 

- (NSInteger)accessibilityElementCount 
{ 
    return [_accessibleElements count]; 
} 

- (id)accessibilityElementAtIndex:(NSInteger)index 
{ 
    return [_accessibleElements objectAtIndex:index]; 
} 

- (NSInteger)indexOfAccessibilityElement:(id)element 
{ 
    return [_accessibleElements indexOfObject:element]; 
} 

@end 


편집 : 나는 업데이트 변화를 시도했습니다 있음을 유의 요소의 accessibilityFrame-indexOfAccessibilityElement:-accessibilityElementAtIndex:의 아이디어와 그것을 필요로하고 그 것 때마다 VoiceOver를 어떻게 든 요소를 ​​요청할 것 사물을 업데이 트하는 좋은 시간. 그러나 그것도 작동하지 않는 것 같습니다. VoiceOver가 자동으로 다시 그리기를 요청하기를 바랬습니다.하지만 작동하지 않는 것 같습니다. (-drawRect:에 위치 설정 코드를 넣는 아이디어는 WWDC에서 내가 기억하는 것으로부터 나온 것이지만, 그것이 "우수 사례"인지 또는 단지 우연한 일인지 분명하지 않았습니다.

+0

시뮬레이터의 버그뿐 아니라 실제 장치에서의 동작을 확인 했습니까? –

+0

예, 기기에서 제대로 작동하지 않습니다. 그것은 조금 다르게 행동하지만, 여전히 내가 기대했던 방식은 아닙니다. – Sean

답변

0

이 문제입니까? VoiceOver 모드에서 앱의 유용성에 영향을 줍니까? Mac OS와 iOS에서 모두 VoiceOver를 사용했을 때 하이라이트 박스 (특히 웹보기)는 화면상의 객체와 비교할 수없는 빈도로 나타납니다. VoiceOver에서 앱을 계속 사용할 수 있다면이 버그를 알려진 버그라고 부르며 누군가 불평하면 해결할 것입니다.

결국 내가 아는 대부분의 시각 장애인들은 강조 상자를보고 있지 않습니다.

1

액세스 가능성 메서드에 일부 부작용을 추가하고 테이블 스크롤 대리자의 공동 작업을 통해 설명한 문제를 해결했습니다. drawRect 메서드 내에서 로컬 직사각형 좌표를 계산하므로 좌표를 변환 할 필요가 없으므로 단순히 셀의 왼쪽 위 모서리와 관련하여 계산합니다.이 초기 뷰에 대해 잘 작동하지만 여전히 를 얻을

- (id)accessibilityElementAtIndex:(NSInteger)index 
{ 
    UIAccessibilityElement *element = [accesible_items_ get:index]; 
    CGRect rect = element.accessibilityFrame; 
    rect.origin.y = 0; 
    element.accessibilityFrame = [self.window 
     convertRect:rect fromView:self]; 
    return element; 
} 

:

그럼,이 같은 부작용으로 프레임을 업데이트하기 위해 접근을 수정합니다 (Y 재설정주의) 난민 프레임 때 사용자가 스크롤, 테이블 뷰 컨트롤러는 다음 스크롤 위임 구현에 있도록 : 테이블의 내용을 모든 세포에 따라

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    // This loop has a side effects, see the cell accesor code. 
    for (id cell in self.tableView.visibleCells) 
     for (int f = 0; [cell accessibilityElementAtIndex:f]; f++); 

    UIAccessibilityPostNotification(
     UIAccessibilityLayoutChangedNotification, nil); 
    NSLog(@"Layout changed after scrollViewDidScroll"); 
} 

을 접근성 방법에 응답 할 수 있으므로 예기치 않은 메시지를 보내지 않으려면 먼저 respondsToSelector으로 각 셀을 쿼리하면됩니다.

UIAccessibilityElement 개체를 만드는 셀 설정자 끝에 UIAccessibilityLayoutChangedNotification을 게시하거나 요소가 사라 졌거나 찾을 수 없다는 로그 메시지가 표시됩니다.

이 변경 사항은 로테이터를 사용하여 요소를 하나씩 반복 할 때 스크롤 작업을 수행하지만, 사용자가 트리플 손가락 동작으로 스크롤하면 여전히 이상한 결과가 발생할 수 있습니다. 기본적으로 tableViews는 한 번에 화면 페이지를 스크롤하기 때문에 셀과 요소 경계가 동일하지 않으며 로터가 셀을 반으로 표시하도록 선택하기 때문입니다. 스크롤 방향과 다른 UI 요소에 따라 반쯤 보이는 셀은 로터가 혼란스럽게되는 컨트롤과 겹칠 수 있습니다. 이 동작을 방지하려면 페이징 된 스크롤을 구현해야합니다.

관련 문제