iOS8 使用动画更改帧时 UITextView 光标低于帧
iOS8 UITextView cursor below frame when changing frame with Animation
我正在尝试在键盘上方显示光标 并使用一些动画 还试图正确滚动 UITextView 背景线。
我已经在 iOS 7 中使用下面的代码完美地解决了这个问题,但它在 iOS 8 上崩溃了,我认为原因是我试图覆盖 scrollRangeToVisible 在 iOS8 中,但我无法这样做,它不像在 iOS7 中那样自动调用。触摸 UITextView 时会显示键盘,因此我无法控制如何滚动内容。我的 UITextView 也有线条。
- (void)textViewDidBeginEditing:(UITextView *)aTextView
{
caretVisibilityTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(scrollCaretToVisible) userInfo:nil repeats:NO];
}
- (void)textViewDidEndEditing:(UITextView *)aTextView
{
[caretVisibilityTimer invalidate];
caretVisibilityTimer = nil;
}
-(void) scrollRangeToVisible: (NSRange) range {
printf("scrollRangeToVisible \n");
}
- (void) scrollCaretToVisible {
printf("scrollCaretToVisible \n");
//[self becomeFirstResponder];
//This is where the cursor is at.
CGRect caretRect = [self caretRectForPosition: self.selectedTextRange.end];
if (CGRectEqualToRect(caretRect, oldRect))
return;
oldRect = caretRect;
//This is the visible rect of the textview.
CGRect visibleRect = self.bounds;
visibleRect.size.height -= (self.contentInset.top + self.contentInset.bottom);
visibleRect.origin.y = self.contentOffset.y;
//We will scroll only if the caret falls outside of the visible rect.
if (!CGRectContainsRect(visibleRect, caretRect)) {
CGPoint newOffset = self.contentOffset;
newOffset.y = MAX((caretRect.origin.y + caretRect.size.height) - visibleRect.size.height, 0);
//Added This section
//=======================================
// Calculates new contentOffset
if (caretRect.origin.y < visibleRect.origin.y)
// rect precedes bounds, scroll up
newOffset.y = caretRect.origin.y - self.contentInset.top - self.bottomPadding;
else
// rect follows bounds, scroll down
newOffset.y = caretRect.origin.y + self.contentInset.bottom + caretRect.size.height - self.bounds.size.height;
//=======================================
/* */
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^ (void)
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^(void)
{
[UIView beginAnimations: nil context: NULL];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
[self setContentOffset: newOffset animated: YES];
[UIView commitAnimations];
});
//[self setContentOffset:newOffset animated:YES];
}
}
参考
UITextView cursor below frame when changing frame
如果有人感兴趣,我发现对于 iOS8,我需要覆盖 scrollRectToVisible,这相当于覆盖 iOS7
中的 scrollRangeToVisible
iOS7
- (void) scrollRangeToVisible:(NSRange)range { }
iOS8
- (void) scrollRectToVisible:(CGRect)rect animated:(BOOL)animated{ [self scrollCaretToVisible]; }
我正在尝试在键盘上方显示光标 并使用一些动画 还试图正确滚动 UITextView 背景线。
我已经在 iOS 7 中使用下面的代码完美地解决了这个问题,但它在 iOS 8 上崩溃了,我认为原因是我试图覆盖 scrollRangeToVisible 在 iOS8 中,但我无法这样做,它不像在 iOS7 中那样自动调用。触摸 UITextView 时会显示键盘,因此我无法控制如何滚动内容。我的 UITextView 也有线条。
- (void)textViewDidBeginEditing:(UITextView *)aTextView
{
caretVisibilityTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(scrollCaretToVisible) userInfo:nil repeats:NO];
}
- (void)textViewDidEndEditing:(UITextView *)aTextView
{
[caretVisibilityTimer invalidate];
caretVisibilityTimer = nil;
}
-(void) scrollRangeToVisible: (NSRange) range {
printf("scrollRangeToVisible \n");
}
- (void) scrollCaretToVisible {
printf("scrollCaretToVisible \n");
//[self becomeFirstResponder];
//This is where the cursor is at.
CGRect caretRect = [self caretRectForPosition: self.selectedTextRange.end];
if (CGRectEqualToRect(caretRect, oldRect))
return;
oldRect = caretRect;
//This is the visible rect of the textview.
CGRect visibleRect = self.bounds;
visibleRect.size.height -= (self.contentInset.top + self.contentInset.bottom);
visibleRect.origin.y = self.contentOffset.y;
//We will scroll only if the caret falls outside of the visible rect.
if (!CGRectContainsRect(visibleRect, caretRect)) {
CGPoint newOffset = self.contentOffset;
newOffset.y = MAX((caretRect.origin.y + caretRect.size.height) - visibleRect.size.height, 0);
//Added This section
//=======================================
// Calculates new contentOffset
if (caretRect.origin.y < visibleRect.origin.y)
// rect precedes bounds, scroll up
newOffset.y = caretRect.origin.y - self.contentInset.top - self.bottomPadding;
else
// rect follows bounds, scroll down
newOffset.y = caretRect.origin.y + self.contentInset.bottom + caretRect.size.height - self.bounds.size.height;
//=======================================
/* */
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^ (void)
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^(void)
{
[UIView beginAnimations: nil context: NULL];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
[self setContentOffset: newOffset animated: YES];
[UIView commitAnimations];
});
//[self setContentOffset:newOffset animated:YES];
}
}
参考 UITextView cursor below frame when changing frame
如果有人感兴趣,我发现对于 iOS8,我需要覆盖 scrollRectToVisible,这相当于覆盖 iOS7
中的 scrollRangeToVisibleiOS7
- (void) scrollRangeToVisible:(NSRange)range { }
iOS8
- (void) scrollRectToVisible:(CGRect)rect animated:(BOOL)animated{ [self scrollCaretToVisible]; }