美文网首页iOS相关
TPKeyBoardAvoiding-研究

TPKeyBoardAvoiding-研究

作者: 9362d9acd9ef | 来源:发表于2017-08-30 09:30 被阅读830次

TPKeyboardAvoiding

There are a hundred and one proposed solutions out there for how to move UITextField and UITextView out of the way of the keyboard during editing -- usually, it comes down to observing UIKeyboardWillShowNotification and UIKeyboardWillHideNotification, or implementing UITextFieldDelegate delegate methods, and adjusting the frame of the superview, or using UITableView's scrollToRowAtIndexPath:atScrollPosition:animated:, but most proposed solutions tend to be quite DIY, and have to be implemented for each view controller that needs it.

解决 UITextField and UITextView 不被弹起的键盘遮盖的作法有很多,通用的方法有两种种

  • 观察 UIKeyboardWillShowNotificationUIKeyboardWillHideNotification 通知
  • 去实现 UITextFieldDelegate delegate,然后通过调整 superview 的 frame,或者 UITableViewscrollToRowAtIndexPath:atScrollPosition:animated: 滑到指定位置

作者认为这样定制性太强

This is a relatively universal, drop-in solution: UIScrollView and UITableView subclasses that handle everything.



When the keyboard is about to appear, the subclass will find the subview that's about to be edited, and adjust its frame and content offset to make sure that view is visible, with an animation to match the keyboard pop-up. When the keyboard disappears, it restores its prior size.



It should work with basically any setup, either a UITableView-based interface, or one consisting of views placed manually.



It also automatically hooks up "Next" buttons on the keyboard to switch through the text fields.

采取的方案是:继承 UIScrollViewUITableView ,把事件 hook 住,实现了下面的功能。

  • 当键盘弹起,子类去找到将要编辑的子视图(subview),调整 framecontent offset 保证子视图不被遮盖。
  • 当键盘消失,恢复弹起前的状态。
  • 在使用 IB 或者 手动布局 的情况都能够起作用。
  • 自动 hook 了 next 按钮

对 TPKeyboardAvoidingTableView 进行分析

在每个初始化函数调用的时候注册事件监听

- (void)setup {
if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil];
}

注册了通知:

  • UIKeyboardWillChangeFrameNotification 键盘的 frame 改变时立刻调用
  • UIKeyboardWillHideNotification 键盘隐藏时调用
  • UITextViewTextDidBeginEditingNotification 有一个 text view 将要进入编辑状态
  • UITextFieldTextDidBeginEditingNotification 有一个 text field 将要进入编辑状态

hasAutomaticKeyboardAvoidingBehaviour

- (BOOL)hasAutomaticKeyboardAvoidingBehaviour {
    if ( [self.delegate isKindOfClass:[UITableViewController class]] ) {
    // Theory: Apps built using the iOS 8.3 SDK (probably: older SDKs not tested) seem to handle keyboard
    // avoiding automatically with UITableViewController. This doesn't seem to be documented anywhere
    // by Apple, so results obtained only empirically.
    return YES;
    }
    return NO;
}

作者在 iOS 8.3 SDK 下猜测 UITableViewController 可能自动对键盘收起做了处理。如果判断使用了 UITableViewController 则代码都不会起作用。

setContentSize

- (void)setContentSize:(CGSize)contentSize {
    if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) {
     [super setContentSize:contentSize];
     return;
    }
    if (CGSizeEqualToSize(contentSize, self.contentSize)) {
        // Prevent triggering contentSize when it's already the same
        // this cause table view to scroll to top on contentInset changes
        return;
    }
    [super setContentSize:contentSize];
    [self TPKeyboardAvoiding_updateContentInset];
}

除了修改 contentSize 会调用,当 contentInset 改变的时候也会调用。

willMoveToSuperview

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    if ( !newSuperview ) {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
    }
}

当 tableView 被加入或移除其他视图的子视图列表中时调用。当 tableView 被释放之类的情况也会调用

相关文章

  • TPKeyBoardAvoiding-研究

    TPKeyboardAvoiding There are a hundred and one proposed s...

  • 研究研究

    爱死佳爷了,龙哥虽然很爆很污但很率直很聪明,事半功倍的事还是要多做一些,我们就是要一路开挂,研究才是硬道理。 芥末...

  • 研究要研究之事

    提到做研究,我总是惶恐的。因为不清楚,不敢轻易开口。在这么多天的看书研究和交流之后,虽然粗粗明白了一些,...

  • 研究

    许岑关于研究原汁原味的分享给大家,仁者见仁,智者见智。不仅用于研究英文,主要是研究的方法论和实操手册,实...

  • 研究

    文/小来 《研究》 我一直想着 能否用最上好的材料 把我的肚子 打造成一口不锈钢锅 以便来防止那些 会把我肠胃弄疼的水货

  • 研究

  • 研究

    要对每一个你身边的人,包括上司和下属进行研究,研究适合他(她)们的相处模式。 有一种沟通模式看来是有效的:从推动工...

  • 研究

    (中国人在国外生活二十年后重拾汉语)探究汉语遗忘规律

  • 研究

    中国手语在汉语初级课堂中的应用可行性

  • 研究

    行业研究下面 分宏观 策略 行业 前两个门槛高 行业研究思路 可以看新闻 看标杆企业 专业词汇 盈利路径 看卖方研...

网友评论

  • LD_左岸:TPKeyboardAvoidingTableView 这个tableView的frame不是整个控制器view的frame时 会报警告 您遇见过吗
    LD_左岸:@雨水钻搭配超 奥解决了是约束警告和这个库没关系:smile:
    9362d9acd9ef:什么警告啊?这个第三方库我也只是简单使用了一下,没有真正放在项目里面

本文标题:TPKeyBoardAvoiding-研究

本文链接:https://www.haomeiwen.com/subject/zwezdxtx.html