Instead of heavy iterated calculations, I'd set complete (starting from the previous page end of course) text to the textView and get the last displayed character position. Then it is easy to perform a fast backward search to truncate the word/sentence.
I've got the following solution, a little tricky part of skipping the last partially displayed line in order to avoid scrolling and make it look nicer. You still need to move endCutIndex
to make it word- or sentence-wrapping.
The base project with the pager but not text-views is taken from 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;
}
Here's a bit of the .h file:
@interface FCContentViewController : UIViewController <UIScrollViewDelegate, UITextViewDelegate>{
UIPageControl *pageControl;
NSString *trunkedString;
UITextView *bodyText;
}
@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, retain) NSString *bodyTextString;