UITextView如何将光标保持在键盘上方

Posted

技术标签:

【中文标题】UITextView如何将光标保持在键盘上方【英文标题】:UITextView how to keep cursor above keyboard 【发布时间】:2015-04-20 02:02:47 【问题描述】:

我有一个 UITextView 占据整个视图的 ViewController,顶部有一个导航栏。几乎就像苹果的“笔记”应用程序。我想要实现的是在编辑开始或编辑时保持文本视图的光标可见。

我能够获得光标的CGPoint,但我很难计算滚动点。我怎样才能做到这一点?

谢谢

当 textview 开始编辑时

- (void)keyboardDidShow:(NSNotification*)aNotification 

    // Keyboard
    NSDictionary *info = [aNotification userInfo];
    CGRect keyPadFrame = [[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:self.view];
    CGSize keyboardSize = keyPadFrame.size;
    kbSize = keyboardSize;

    [self scrollToCursor];

textview 编辑时

- (void)textViewDidChange:(UITextView *)textView 
    // Scroll to cursor
    [self scrollToCursor];

滚动到光标方法

- (void)scrollToCursor 
    // View
    CGRect viewBounds = self.view.bounds;
    CGRect visibleViewBounds = CGRectMake(viewBounds.origin.x,
                                          viewBounds.origin.y + (self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height),
                                          viewBounds.size.width,
                                          viewBounds.size.height - (kbSize.height + self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height));

    // TextView
    CGPoint textViewOrigin = [self.view convertRect:self.noteTextView.frame fromView:self.noteTextView.superview].origin;

    // Cursor
    CGPoint textViewCursor = [self.noteTextView caretRectForPosition:self.noteTextView.selectedTextRange.start].origin;
    CGPoint cursorPoint = CGPointMake((textViewCursor.x + textViewOrigin.x), (textViewCursor.y - self.noteTextView.contentOffset.y));

    // Scroll to point
    if (!CGRectContainsPoint(visibleViewBounds, CGPointMake(cursorPoint.x, cursorPoint.y + 25/*25 for cursor's height*/))) 
        [self.noteTextView setContentOffset:CGPointMake(0, 0)/*How to calculate??*/ animated:YES];
    

【问题讨论】:

你知道键盘的高度,就可以得到屏幕的大小。如果你有光标的CGPoint。您可以将 y 添加到键盘的高度(加上任何填充)并将其从屏幕的高度移开。这会给你滚动到的 y 值。 @Siiss 感谢您的回复!您介意用代码发布答案吗? 【参考方案1】:

这根本没有经过测试,但将是我的第一次尝试。

通过监听KeyboardWillChangeFrameNotification获取键盘高度

CGRect keyboardFrame;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void)keyboardWillChange:(NSNotification *)notification 
    keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardFrame = [self.view convertRect:keyboardRect fromView:nil];

这将为您提供键盘高度。

然后获取屏幕高度:

CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;  
CGFloat screenHeight = screenSize.height;

那么如果你知道光标的CGPoint,就做这样的事情:

CGFloat keyboardTop = (screenHeight - (keyboardFrame.size.height + <padding if you want it>));
if (currentCursorPosition.y > keyboardTop)

 [self.noteTextView setContentOffset:CGPointMake(0, (cursorPoint.y - (viewBounds.size.height - kbSize.height)) + self.noteTextView.contentOffset.y + 25);

理想情况下,这应该将光标保持在键盘顶部,然后在向下移动光标时滚动。

【讨论】:

hmm...我将滚动点指向CGPointMake(0, cursorPoint.y - (viewBounds.size.height - kbSize.height)),但它无法正常工作。有时它会滚动一点点,有时它会滚动得超出应有的范围......我不确定哪里出了问题:( 好的,我终于让它工作了。它缺少 textview 的 contentOffSet。我做了CGPointMake(0, (cursorPoint.y - (viewBounds.size.height - kbSize.height)) + self.noteTextView.contentOffset.y + 25)。您能否更新您的答案以便我接受? 当然可以。太好了,你得到它的工作,并感谢分享解决方案!【参考方案2】:

为了您的理智,请使用库。

这是一个很好的:https://github.com/hackiftekhar/IQKeyboardManager

迦太基:

github“hackiftekhar/IQKeyboardManager”

CocoaPods:

pod 'IQKeyboardManagerSwift', '6.3.0'

pod 'IQKeyboardManager', '3.3.7' #ios7

【讨论】:

以上是关于UITextView如何将光标保持在键盘上方的主要内容,如果未能解决你的问题,请参考以下文章

光标在 UITextView 中的奇怪定位

如何滚动到 UITextView 中的当前光标位置?

如何将 UITableViewCell 中的 UITextView 滚动到键盘顶部?

是否有任何通用解决方案可以在屏幕上的键盘上方滚动 UITextView 和 UITextField

将光标放在用户触摸的 UITextView 上

UITextView在输入时隐藏文本