2012-10-22 3 views
1

현재 RSS 피드를 읽고 긴 paragraphed 텍스트를 페이징이 활성화 된 UIScrollView로 분리하려고합니다. 나는 텍스트를 각기 다른 페이지로 분리해야 할 필요가있다. 각각의 페이지에 맞을 것이고 그만큼 문자열을 분리 할 필요가있다. 나는 이것을하는 표준이 있는지 확실하지 않고 이것이 대부분의 RSS 읽기 응용 프로그램이 여러 페이지에서 정보를 분리하는 방법이라고 가정합니다. 누구든지이 문제를 해결하는 방법을 알고 있습니까? 나는 그 편지가 적합하지 않고 계속 될 때까지 편지로 편지를보고 싶지 않았다.문자열 분리 방법 프레임 크기에 따라 UIScrollView/UITextView

편집 :

이 좋은 시작이지만, 문제에 예제 코드를 꽤 많이 실행 내가 피하려고 노력하고 주위 얻을하는 방법을 모르겠어요. 이 범위는 UITextView에 대해 잘못 계산합니다. 아래에서 볼 수있는 글꼴 등을 바꿉니다. 모든 것이 - (NSRange) visibleRangeOfTextView : (UITextView *) textView 내에서 계산되고 있습니다. 이 메소드는 UITextView의 텍스트를 설정 한 후 외부 클래스가 호출하는 - (void) adjustTextDisplay에 의해 호출됩니다. 컨텐츠 크기를 화면의 프레임 크기로 설정해도보기가 제한되지 않고 (아래 그림 참조) 왜이 메소드가 전체 문자열 길이를 범위로 반환하는지 알 수없는 이유는 모르겠다.

답변

0

아이폰 OS 7으로는 많이있다 아래 예제 코드에 포함 된 TextKit을 사용하여보다 세련된 솔루션을 제공합니다. 아이디어는 TextKit의 레이아웃 관리자가 글리프를 분리하고 모든 것을 적절하게 배치하도록하는 것입니다. 이것은 중간에 단어와 유연성의 톤을 차단하지 못하도록 방지합니다.

class BookView: UIScrollView { 

    var bookMarkup: NSAttributedString! 
    private let layoutManager = NSLayoutManager() 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     if layoutManager.textContainers.count == 0 { 
      buildFrames() 
     } 
    } 

    func buildFrames() { 
     let textStorage = NSTextStorage(attributedString: bookMarkup) 

     textStorage.addLayoutManager(layoutManager) 

     var range = NSMakeRange(0, 0) 
     var containerIndex = 0 

     while NSMaxRange(range) < layoutManager.numberOfGlyphs { 
      let textViewRect = frameForViewAtIndex(containerIndex) 
      let containerSize = CGSizeMake(CGRectGetWidth(textViewRect), CGRectGetHeight(textViewRect) - 16) //UITextView adds an 8 margin above and below the container so we take that into consideration here with the 16. heightTracksTextView causes a performance hit when adding multiple containers... so we don't do that instead 
      let textContainer = NSTextContainer(size: containerSize) 
      layoutManager.addTextContainer(textContainer) 

      let textView = UITextView(frame: textViewRect, textContainer: textContainer) 

      addSubview(textView) 

      containerIndex++ 

      range = layoutManager.glyphRangeForTextContainer(textContainer) 
     } 

     contentSize = CGSize(width: CGRectGetWidth(bounds)/2 * CGFloat(containerIndex), height: CGRectGetHeight(bounds)) 

     pagingEnabled = true 
    } 

    private func frameForViewAtIndex(index: Int) -> CGRect { 

     var textViewRect = CGRect(origin: CGPointZero, size: CGSize(width: CGRectGetWidth(bounds)/2, height: CGRectGetHeight(bounds))) 
     textViewRect = CGRectInset(textViewRect, 10, 20) 
     textViewRect = CGRectOffset(textViewRect, CGRectGetWidth(bounds)/2 * CGFloat(index), 0) 
     return textViewRect 
    } 
} 
3

무거운 반복 계산 대신에 textView와 get the last displayed character position으로 텍스트를 완료 (이전 페이지 끝에서 시작)로 설정했습니다. 그런 다음 빠른 역방향 검색을 수행하여 단어/문장을 자르기가 쉽습니다.


나는 다음과 같은 솔루션, 스크롤을 방지하고 좋네요 보이게하기 위해 마지막 부분 표시 줄을 건너 뛰는 조금 까다로운 부분이 있어요. 단어 또는 문장 줄 바꿈을하려면 endCutIndex으로 이동해야합니다.

호출기가 아닌 텍스트 뷰와 기본 프로젝트는 여기에 .H 파일의 비트의 here

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    NSString * fullText = @"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda."; 

    pageControlBeingUsed = NO; 


    int pageNumber = 0; 
    UIFont * theFont = [UIFont boldSystemFontOfSize:30]; 
    const CGSize charSize = [@"A" sizeWithFont:theFont]; 

    while (fullText.length > 0) { 
     CGRect frame; 
     frame.origin.x = self.scrollView.frame.size.width * (pageNumber++); 
     frame.origin.y = 0; 
     frame.size = self.scrollView.frame.size; 

     UIView *subview = [[UIView alloc] initWithFrame:frame]; 

     UITextView * textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; 
     textView.font = theFont; 
     [subview addSubview:textView]; 
     [textView release]; 


     textView.text = fullText; 

     CGRect bounds = textView.bounds; 
     // - charSize.height to skip a partially visible line 
     // - charSize.width*2 to skip annoying character still displayed at partially visible line 
     CGPoint endPoint = CGPointMake(CGRectGetMaxX(bounds) - charSize.width*2, CGRectGetMaxY(bounds) - charSize.height); 
     UITextPosition *start = [textView characterRangeAtPoint:bounds.origin].start; 
     UITextPosition *end = [textView characterRangeAtPoint:endPoint].end; 

     const int startCutIndex = [textView offsetFromPosition:textView.beginningOfDocument toPosition:start]; 
     const int endCutIndex = [textView offsetFromPosition:textView.beginningOfDocument toPosition:end]; 

     NSString * cutText = [fullText substringToIndex:endCutIndex]; 
     textView.text = cutText; 
     fullText = [fullText substringFromIndex:endCutIndex]; 

     [self.scrollView addSubview:subview]; 
     [subview release]; 

     NSLog(@"Page (1-total) %d, start text index %d, end text index %d \ntext:%@", pageNumber, startCutIndex, endCutIndex, cutText); 
    } 

    const int totalPages = pageNumber; 

    self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * totalPages, self.scrollView.frame.size.height); 

    self.pageControl.currentPage = 0; 
    self.pageControl.numberOfPages = totalPages; 
} 

에서 가져온 것입니다 :

@interface FCContentViewController : UIViewController <UIScrollViewDelegate, UITextViewDelegate>{ 
    UIPageControl *pageControl; 
    NSString *trunkedString; 
    UITextView *bodyText; 
} 
@property (nonatomic, retain) UIScrollView *scrollView; 
@property (nonatomic, retain) NSString *bodyTextString; 
+0

나는 이것을 성공시키지 않고 춤추려고했습니다. 위의 코드를 살펴보십시오. 이러한 종류의 솔루션은 내가 찾고있는 것이지만 작동하지 않으며 코드를 여러 가지 방식으로 변경하여 내 마음에 드는 방식으로 시도했습니다. UITextView 내에서 전체 텍스트의 마지막 문자를 가져옵니다. 즉, UITextView의 스크롤링 부분으로 잘린 모든 텍스트를 가져옵니다. 본문 텍스트 문자열은 항상 반환 된 길이로 나옵니다. – TheCodingArt

+0

반환 할 생성 된 범위의 두 번째 인수로'[self.textView offsetFromPosition : self.textView.beginningOfDocument toPosition : end]'여야합니다. 이 방법은 나를 위해 잘 작동합니다. 이제는 부분적으로 보이는 텍스트가'characterRangeAtPoint :'에 의해 감지되는 문제가 있지만, 반드시 그 텍스트가 마지막 textView.text 문자는 아니어야합니다. –

+0

Arg, 방금 시도했는데 성공하지 못한 채로 시도해 보았습니다. 위 콘솔 출력에 수정 된 코드를 추가했습니다. 또한 텍스트가있는 화면을 추가했습니다. 텍스트가 거의 모든 추가 단락으로 이어지는 것에 유의하십시오 (단 한 줄이 아님). 그것은 여전히 ​​잘못된 단어를 반환하는 끝에 대한 값입니다, 그래서이 문제는 반환 된 입력 훨씬 전에 발생합니다. – TheCodingArt