I have an UIView
and I add a editable UITextView
to it,
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 2
if found a solution
i put the textview into a view and set the view to clipToBounds = YES then i put the textView to a height of 70
that fixed the problem.
very strange solution, but it finally works :)
I think you'll have to do
[textView scrollRangeToVisible:[textView selectedRange]];
in textDidChange
.
To scroll to the end of the buffer I tried
[textView scrollRangeToVisible:NSMakeRange([textView.text length]-1, 1)];
But nothing happened. Instead this works
textView.selectedRange = NSMakeRange(textView.text.length - 1, 0);
I found that if the text added to the UITextView contained carriage returns, then the textview would not scroll correctly.
I added the logic as follows to allow the bounds to be correctly calculated before scrolling to range.
BOOL autoscroll = NO;
//I added a 10 px buffer here to allow for better detection as the textview is auto populated
if (textView.contentOffset.y >= (textView.contentSize.height - textView.frame.size.height - 10))
{
autoscroll = YES;
}
[textView setText:messageString];
[textView layoutSubviews];
if(autoscroll) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[textView scrollRangeToVisible:NSMakeRange(textView.text.length - 1, 1)];
});
}
When adding text to a text box programmatically, I found I also needed to add "[textView layoutIfNeeded]" to set things up before the new scroll position could be calculated correctly.
for example:
[newString appendFormat:@"%@\n",addText];
textView.text = newString;
[textView layoutIfNeeded];
NSRange range = NSMakeRange(textView.text.length - 2, 1); //I ignore the final carriage return, to avoid a blank line at the bottom
[textView scrollRangeToVisible:range]
Without this addition the textbox would sometimes not scroll, or would scroll several lines every time a single line of data was added.
This works:
- (void)textViewDidChange:(UITextView *)textView {
if (_moveToBottom) {
int y = textView.contentSize.height - textView.frameHeight + self.textView.contentInset.bottom + self.textView.contentInset.top;
if(y > 0) {
[textView setContentOffset:CGPointMake(0, y) animated:YES];
}
_moveToBottom = NO;
}
else {
[textView scrollRangeToVisible:NSMakeRange([textView.text length]-1, 1)];
}
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:@"\n"] && range.location == [textView.text length]) {
_moveToBottom = YES;
}
return YES;
}