如何让光标在UITextView中自动可见
1个回答
2015-08-10 · 知道合伙人软件行家
关注
展开全部
正常情况下在UITextView中系统会自动处理光标可见,然而实际开发中产品设计并不会局限于系统本身的空间,但作为开发者必须尽其所能的去实现,满足产品设计,达到最佳的用户体验,才能让产品有立足之地。
下面有一种情形可能是我们经常遇到的,如邮件的编辑界面。
该界面有如下控件
UITextField *toTextField; // 收件人
UITextField *ccTextField; // 抄送
UITextField *subjectTextField; // 主题
UITextView *contentTextView; // 内容
如果内容过多时,就显示不全,那么我们还必须加一个UIScrollView将上面的控件包着,支持上下滑动界面,以便查看所有内容
UIScrollView *scrollView;
也许有人发现,textView本身是可以滑动的,而scrollView也可以滑动,这样会造成体验非常糟糕的结果。这种糟糕的体验起码我是决不能让其发生的,相信大家也是如此。
解决方案就是让textView的frame自适应其contentSize,然后再动态改变scrollview的contentSize,这样textview就不会独自滑动了。
上边的具体实现,相信大部分人都能知道。然后实现过的人又会遇到一个棘手的问题,内容过多时,光标不会自动向上移动,导致光标不见了。就是在这篇文章主要介绍的问题:“光标自动可见”
// 这里只介绍textview 自适应及光标自动可见的问题,所以其他的细节都省略。
#pragma mark -- KVO --
- (void)addContentView
{
contentTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 157, 320.0f, 346)];
// 设置底部间距50,这个非常重要。不加的话,会出现异常的问题,可以自己动手试一试
contentTextView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
// 使用KVO 观察contentSize的动态
[contentTextView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
CGSize size = scrollView.frame.size;
size.height = CGRectGetMaxY(contentTextView.frame);
scrollView.contentSize = size;
[scrollView addSubview: contentTextView]
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
// 监听textview 的contensize是否改变
if ([keyPath isEqualToString:@"contentSize"])
{
UITextView *view = object;
// 获取textView最新的contentSize的高度
CGFloat contentHeight = view.contentSize.height;
CGSize scrollViewContentSize = scrollView.contentSize;
if (contentHeight > 346) { // 346 是textview的默认高度
CGRect frame = view.frame;
frame.size.height = contentHeight + 50; // 50 是底部间距
view.frame = frame;
scrollViewContentSize.height = view.frame.origin.y + view.frame.size.height;
}else {
scrollViewContentSize.height = view.frame.origin.y + view.frame.size.height - 14;
}
scrollView.contentSize = scrollViewContentSize;
// 获取光标的位置区域
CGRect cursorPosition = [view caretRectForPosition:view.selectedTextRange.start];
// 光标相对顶层视图(scrollView)frame的坐标高度
CGFloat height = cursorPosition.origin.y + view.frame.origin.y - _mailScrollView.contentOffset.y;
//
CGFloat currentPoint = cursorPosition.origin.y;
// 可见scrollView区域, 由于键盘有中英输入法,所以会导致可见区域的变化
CGFloat cursorValueMax = [UIScreen mainScreen].bounds.size.height - 64 - self.keyboard.keyboardHeight;
if (height > cursorValueMax - 50) { // 当光标在可见区域底部50pix内,即距离键盘50pix内
[scrollView setContentOffset:CGPointMake(0, currentPoint + view.frame.origin.y - cursorValueMax + 50) animated:YES];
} else if (height < 20) { // 当光标在可见区域顶部20pix内,即距离顶部20pix内
[scrollView scrollRectToVisible:CGRectMake(0, cursorPosition.origin.y - 20, 320, 60) animated:YES];
}
}
}
下面有一种情形可能是我们经常遇到的,如邮件的编辑界面。
该界面有如下控件
UITextField *toTextField; // 收件人
UITextField *ccTextField; // 抄送
UITextField *subjectTextField; // 主题
UITextView *contentTextView; // 内容
如果内容过多时,就显示不全,那么我们还必须加一个UIScrollView将上面的控件包着,支持上下滑动界面,以便查看所有内容
UIScrollView *scrollView;
也许有人发现,textView本身是可以滑动的,而scrollView也可以滑动,这样会造成体验非常糟糕的结果。这种糟糕的体验起码我是决不能让其发生的,相信大家也是如此。
解决方案就是让textView的frame自适应其contentSize,然后再动态改变scrollview的contentSize,这样textview就不会独自滑动了。
上边的具体实现,相信大部分人都能知道。然后实现过的人又会遇到一个棘手的问题,内容过多时,光标不会自动向上移动,导致光标不见了。就是在这篇文章主要介绍的问题:“光标自动可见”
// 这里只介绍textview 自适应及光标自动可见的问题,所以其他的细节都省略。
#pragma mark -- KVO --
- (void)addContentView
{
contentTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 157, 320.0f, 346)];
// 设置底部间距50,这个非常重要。不加的话,会出现异常的问题,可以自己动手试一试
contentTextView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
// 使用KVO 观察contentSize的动态
[contentTextView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
CGSize size = scrollView.frame.size;
size.height = CGRectGetMaxY(contentTextView.frame);
scrollView.contentSize = size;
[scrollView addSubview: contentTextView]
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
// 监听textview 的contensize是否改变
if ([keyPath isEqualToString:@"contentSize"])
{
UITextView *view = object;
// 获取textView最新的contentSize的高度
CGFloat contentHeight = view.contentSize.height;
CGSize scrollViewContentSize = scrollView.contentSize;
if (contentHeight > 346) { // 346 是textview的默认高度
CGRect frame = view.frame;
frame.size.height = contentHeight + 50; // 50 是底部间距
view.frame = frame;
scrollViewContentSize.height = view.frame.origin.y + view.frame.size.height;
}else {
scrollViewContentSize.height = view.frame.origin.y + view.frame.size.height - 14;
}
scrollView.contentSize = scrollViewContentSize;
// 获取光标的位置区域
CGRect cursorPosition = [view caretRectForPosition:view.selectedTextRange.start];
// 光标相对顶层视图(scrollView)frame的坐标高度
CGFloat height = cursorPosition.origin.y + view.frame.origin.y - _mailScrollView.contentOffset.y;
//
CGFloat currentPoint = cursorPosition.origin.y;
// 可见scrollView区域, 由于键盘有中英输入法,所以会导致可见区域的变化
CGFloat cursorValueMax = [UIScreen mainScreen].bounds.size.height - 64 - self.keyboard.keyboardHeight;
if (height > cursorValueMax - 50) { // 当光标在可见区域底部50pix内,即距离键盘50pix内
[scrollView setContentOffset:CGPointMake(0, currentPoint + view.frame.origin.y - cursorValueMax + 50) animated:YES];
} else if (height < 20) { // 当光标在可见区域顶部20pix内,即距离顶部20pix内
[scrollView scrollRectToVisible:CGRectMake(0, cursorPosition.origin.y - 20, 320, 60) animated:YES];
}
}
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询