2012-06-08 1 views
0

일련의 타자기 페이지와 같이 작동하는 NSTextView를 만들려고합니다. 각 페이지에는 사용할 수있는 행과 열의 수가 고정되어 있습니다.NSTextView의 하드 래핑

기본 표현은 이상적으로 디스플레이와 일치하며, 차례로 파일 형식과 일치합니다. 페이지는 양식 피드 문자 '\f'으로 끝납니다. 에 포함되지 않습니다

  • 뉴 라인과 폼 피드 :

    T H I S \n 
    P A G E \n 
    I S \n 
    F U L L \n 
    \f 
    N O T \n 
    T H I S \n 
    O N E \n 
    \n 
    \f 
    

    몇 가지 주목할 : (읽기 쉽도록 글자 사이에 공백을) 저장할 때 예를 들어, 두 개의 4 × 4 페이지는 다음과 같이 보일 것이다 패딩입니다 계산 행보다 짧은

  • 페이지 (에디터가 덮어 쓰기 모드 일 경우가있을 수 있지만) 열 수보다 짧은 행/열 전체
  • 선 후행 공백으로 채워되지 않습니다 i 번째는

내가 다음 연결된 라인의 텍스트를 설정, 모든 textDidChange 통지에 라인과 분할 긴 줄의 NSArray에 텍스트를 변환과 같은 몇 가지 방법을 시도 줄 바꿈,하지만 정말 비효율적이며, 커서를 잃는다 문서의 끝 부분을 제외하고 어디에서나 입력이 발생하면 위치에 놓습니다.

결국 이것은 공백으로 채워진 큰 페이지로 동작하고 입력은 덮어 쓰기 모드에서만 발생하지만 줄 끝 부분에서는 줄 바꿈됩니다. 그 접근법으로 어디서부터 시작해야할지 모르겠습니다. 어떤 제안?

+0

더 기본적인 질문? 이 문제를 해결할 수있는 가장 좋은 장소가 텍스트보기, 레이아웃 관리자, 식자 도구, 텍스트 저장소 또는 다른 곳에 있는지 여부는 확실하지 않습니다. 어쩌면 올바른 방향의 포인터 만 있으면 나머지 부분을 파악할 수 있습니다. – squidpickles

답변

0

NSTextStorage을 서브 클래스 화하여 랩핑을위한 완벽한 해결책은 아닌 것으로 나타났습니다.

붙여 넣기 여부에 상관없이 문서 끝에 텍스트를 추가 할 때 예상대로 작동합니다. 텍스트를 삭제하거나 대체 할 때도 작동합니다. 조금 이상한 유일한 곳은 이미 전체 라인의 중간에 텍스트를 삽입 할 때입니다. 그러면 앞에 랩을 넣고 앞에 삽입 된 텍스트가 표시됩니다. 잘 작동하지만 그 위치에 계속 입력하면 여러 개의 짧은 줄이 생깁니다.

예를 들어 아래 텍스트는 20 열로 줄 바꿈됩니다. 원본 텍스트는 x이고 삽입 된 텍스트는 o입니다. 삽입 된 텍스트는 두 번째 줄, 즉 8 번째 문자에서 시작됩니다. 아래

xxxxxxxxxxxxxxxxxxxx 
xxxxxxx 
ooooooo 
ooooooo 
oooooooxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxx 

코드 : 아마도

- (void)breakLinesInArray:(NSMutableArray *)lines atLength:(NSUInteger)length 
charsPreceding:(NSUInteger)preceding charsFollowing:(NSUInteger)following 
{ 
    NSUInteger line = 0; 
    while (line < [lines count]) { 
     NSUInteger maxLineLength = length; 
     if (line == 0) { 
      maxLineLength = length - preceding; 
     } else if (line == [lines count] - 1) { 
      maxLineLength = length - following; 
     } 
     NSString *original = [lines objectAtIndex:line]; 
     if (maxLineLength > 0 && [original length] > maxLineLength) { 
      NSString *first = [original substringToIndex:maxLineLength]; 
      NSString *second = [original substringFromIndex:maxLineLength]; 
      [lines replaceObjectAtIndex:line withObject:first]; 
      [lines insertObject:second atIndex:line + 1]; 
     } 
     ++line; 
    } 
} 

- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str 
{ 
    static const NSUInteger kMaxLineLength = 20; 
    NSString *text = [text_ string]; 
    NSUInteger firstLineStart = 0; 
    NSUInteger lastLineEnd = 0; 
    NSMutableArray *lines = [NSMutableArray arrayWithArray:[str componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]]; 
    [text getLineStart:&firstLineStart end:nil contentsEnd:&lastLineEnd forRange:range]; 
    NSUInteger firstLineStartFragmentLength = range.location - firstLineStart; 
    NSUInteger lastLineEndFragmentLength = lastLineEnd - (range.location + range.length); 
    [self breakLinesInArray:lines atLength:kMaxLineLength charsPreceding:firstLineStartFragmentLength charsFollowing:lastLineEndFragmentLength]; 
    NSString *newString = [lines componentsJoinedByString:@"\n"]; 
    NSInteger changeInLength = [newString length] - range.length; 
    NSInteger newLastLineLength = firstLineStartFragmentLength + lastLineEndFragmentLength + changeInLength; 
    if ((firstLineStartFragmentLength || lastLineEndFragmentLength) && newLastLineLength > (NSInteger)kMaxLineLength) { 
     newString = [@"\n" stringByAppendingString:newString]; 
     ++changeInLength; 
    } 
    [text_ replaceCharactersInRange:range withString:newString]; 
    [self edited:NSTextStorageEditedCharacters range:range changeInLength:changeInLength]; 
}