2014-04-02 6 views
10

UIAccessibilityReadingContent 프로토콜을 지원하려면 해당 회선에 대한 질문에 대답하기 위해 UITextView가 필요합니다. 이 내가 구현하는 데 필요한 프로토콜의 방법은 다음과 같습니다UITextView 및 NSLayoutManager에서 회선 정보 가져 오기

  • accessibilityLineNumberForPoint: <-
  • accessibilityFrameForLineNumber: < 주어진 행의 텍스트를 반환 - - 감안할 행 번호
  • accessibilityContentForLineNumber: <을, 좌표 반환 제공 줄 번호, 프레임 반환
  • accessibilityPageContent < - 전체 텍스트 내용입니다. 내가 가진 것. :)

나는 NSLayoutManager가 나를 도울 수 있다고 생각하지만, 나는 그것에 익숙하지 않다. 나는 그것의 일부를 알아 냈는데 (나는 생각한다.), 그러나 여전히 도움이 필요하다.

NSLayoutManager *layoutManager = [textView layoutManager]; 
unsigned numberOfLines, index, numberOfGlyphs = 
     [layoutManager numberOfGlyphs]; 
NSRange lineRange; 
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ 
    (void) [layoutManager lineFragmentRectForGlyphAtIndex:index 
      effectiveRange:&lineRange]; 
    index = NSMaxRange(lineRange); 
} 

내가 선이 NSLayoutManager에이 방법을 사용의 구형 위 lineRange으로, 내가 계산할 수 있음을 알 :

애플은 텍스트보기 나에게 줄 수를 얻을 수있는 몇 가지 샘플 코드 (here)가 :

- (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container 

그리고 주어진 lineRanges 나는 문자 모양 인덱스를 포함하는 lineRange을 찾아 (사용 포인트의 행 수를 계산 할 수 있어야한다 :

- (NSUInteger)glyphIndexForPoint:(CGPoint)point inTextContainer:(NSTextContainer *)container fractionOfDistanceThroughGlyph:(CGFloat *)partialFraction 

그럼 남아있는 것은 줄 번호가 주어진 경우 (NSString) 어떻게 줄 내용을 얻습니까? 당신의 클래스 다음

self.ranges = ranges; 
self.frames = frames; 
self.numberOfLines = numberOfLines; 

당신은 할 수 있습니다 : 쉬운 솔루션에 생각

+0

이 프로토콜이 필요한지 확실합니다. 일반적으로 NSTextStorage, NSLayoutManager 및 NSTextContainer를 설정할 수 있으며 모든 것이 정상입니다. 나는 그것에 관하여 중대한 화제를 읽었다 : http://www.raywenderlich.com/50151/text-kit-tutorial. – kaspartus

+0

불행히도 예. VoiceOver가 활성화되어있을 때 UITextView가 라인에서 한 줄씩 읽는 것을 제공하지 않는 것 같습니다. 최소한 내 구현에서는 (UITableViewCells에 포함 된 UITextViews) –

+0

'NSLayoutManager'는 문자 범위를 사용하는 메소드와 문자 범위를위한 메소드를 제공합니다. 마지막으로 두 범위 사이에서 변환 할 수있는 두 가지 메소드가 있습니다 :'- [NSLayoutManager glyphRangeForCharacterRange : actualCharacterRange :]'와'- [NSLayoutManager characterRangeForGlyphRange : actualGlyphRange :]'. 문자열을 검색하려면 관심있는 glyphRange를 characterRange로 변환하면'attributedSubstringFromRange :'또는'string'과'substringWithRange :'를 사용하여'UITextView'의'textStorage'에서 하위 문자열을 검색 할 수 있습니다. – Dalzhim

답변

4

, 여기 당신이

- (void)analyse:(UITextView *)textView 
{ 
    NSLayoutManager *layoutManager = [textView layoutManager]; 
    NSString *string = textView.text; 
    unsigned numberOfLines, index, stringLength = [string length]; 

    NSMutableArray *ranges = [NSMutableArray new]; 
    NSMutableArray *frames = [NSMutableArray new]; 
    for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++) 
    { 
     NSRange tmprange; 
     NSRange range = [string lineRangeForRange:NSMakeRange(index, 0)]; 
     CGRect rect = [layoutManager lineFragmentRectForGlyphAtIndex:index 
              effectiveRange:&tmprange]; 

     [ranges addObject:[NSValue valueWithRange:range]]; 

     [frames addObject:[NSValue valueWithCGRect:rect]]; 
     index = NSMaxRange(range); 
    } 
    self.ranges = ranges; 
    self.frames = frames; 
    self.numberOfLines = numberOfLines; 
} 

이 속성 봐 주시기 바랍니다 필요 재현 작은 코드 이 속성을 만들려면 :

@property (nonatomic) NSInteger numberOfLines; 
@property (strong, nonatomic) NSArray *ranges; 
@property (strong, nonatomic) NSArray *frames; 

나는 당신이 followi 안에 분석 통화를 추가하는 것이 좋습니다 NG 위임 :

- (void)textViewDidChange:(UITextView *)textView 

당신은 예를 들어 후 불과하고 2 라인의 프레임을 얻을 분석 할 수 있습니다 : self.frames [1]

또는 일을 두 번째 줄의 텍스트를 받고 : [textView.text substringWithRange [self.ranges [1] rangeValue] 이런 예

:

if (self.numberOfLines > 1) 
{ 
    NSRange range = [self.ranges[1] rangeValue]; 
    NSLog(@"2nd line = %@", [textView.text substringWithRange:range]); 
    NSLog(@"2nd line frame = %@", self.frames[1]); 
} 

모든 프레임이 인 self.frames 다른 것을 쉽게 할 수 있다고 생각합니다. 좌표를 사용하여 줄 번호를 추측 해보십시오.

+0

나는 당신의 아름다운 해결책에서 약간의 실수를 발견했다. 올바른 수의 줄을 얻기 위해서는'index = NSMaxRange (range);'대신'index = NSMaxRange (tmpRange);'를 사용해야한다. 9.3에서 실행. 그렇지 않으면 솔루션이 완벽합니다. :-) –