『零行代码』解决键盘遮挡问题(iOS)

481 查看

关注仓库,及时获得更新:iOS-Source-Code-Analyze

Follow: Draveness · Github

icon

Icon

这篇文章会对 IQKeyboardManager 自动解决键盘遮挡问题的方法进行分析。

最近在项目中使用了 IQKeyboardManager 来解决 UITextField 被键盘遮挡的问题,这个框架的使用方法可以说精简到了极致,只需要将 IQKeyboardManager 加入 Podfile,然后 pod install 就可以了。

这篇文章的题目《零行代码解决键盘遮挡问题》来自于开源框架的介绍:

Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView. Neither need to write any code nor any setup required and much more.

因为在项目中使用了 IQKeyboardManager,所以,我想通过阅读其源代码来了解这个黑箱是如何工作的。

虽然这个框架的实现的方法是比较简单的,不过它的实现代码不是很容易阅读,框架因为包含了很多与 UI 有关的实现细节,所以代码比较复杂。

架构分析

说是架构分析,其实只是对 IQKeyboardManager 中包含的类以及文件有一个粗略地了解,研究一下这个项目的层级是什么样的。

1

IQKeyboardManager-Hierarchy

整个项目中最核心的部分就是 IQKeyboardManager 这个类,它负责管理键盘出现或者隐藏时视图移动的距离,是整个框架中最核心的部分。

在这个框架中还有一些用于支持 IQKeyboardManager 的分类,以及显示在键盘上面的 IQToolBar:

2

IQToolBa

使用红色标记的部分就是 IQToolBar,左侧的按钮可以在不同的 UITextField 之间切换,中间的文字是 UITextField.placeholderText,右边的 Done 应该就不需要解释了。

这篇文章会主要分析 IQKeyboardManager 中解决的问题,会用小篇幅介绍包含占位符(Placeholder) IQTextView 的实现。

IQTextView 的实现

在具体研究如何解决键盘遮挡问题之前,我们先分析一下框架中最简单的一部分 IQTextView 是如何为 UITextView 添加占位符的。

IQTextView 继承自 UITextView,它只是在 UITextView 上添加上了一个 placeHolderLabel

在初始化时,我们会为 UITextViewTextDidChangeNotification 注册通知:

在每次 UITextView 中的 text 更改时,就会调用 refreshPlaceholder 方法更新 placeHolderLabelalpha 值来隐藏或者显示 label:

IQKeyboardManager

下面就会进入这篇文章的正题:IQKeyboardManager

如果你对 iOS 开发比较熟悉,可能会发现每当一个类的名字中包含了 manager,那么这个类可能可能遵循单例模式,IQKeyboardManager 也不例外。

IQKeyboardManager 的初始化

IQKeyboardManager 初始化的时候,它做了这么几件事情:

  1. 监听有关键盘的
  2. 注册与 UITextField 以及 UITextView 有关的通知
    • 调用的方法将通知绑定到了 textFieldViewDidBeginEditing:textFieldViewDidEndEditing: 方法上