iOS Swift 5中的键盘处理

This article was originally published at CometChat.

本文最初在CometChat上发布。

“Handling Keyboard in iOS” — This has been a topic or rather a problem since the inception of iOS Development. Whether you are a beginner developer or an experienced one, you’ll always be dealing with the handling of keyboards in your apps! But there’s not just 1 issue with the keyboard that we are talking about here. We have to manually handle a couple of issues. Here, let me show you exactly what I mean -

“ iOS中的键盘处理” —自iOS开发以来,这一直是一个话题,甚至是一个问题。 无论您是初学者还是经验丰富的开发人员,您都将始终在处理应用程序中的键盘操作! 但是我们在这里谈论的不仅仅是键盘的1个问题。 我们必须手动处理几个问题。 在这里,让我告诉您我的确切意思-

Manually handle the dismissal of the keyboard

手动处理键盘的关闭

Image for post

When you tap on a text-field, the keyboard pops up and allows you to type in whatever you want. Now once you are done writing, there is no default done button which will dismiss the keyboard, tapping outside the keyboard ain’t gonna do anything either. It’s like iOS saying — “Isn’t it enough I popped up the keyboard automatically for you? Figure out a way to make it go away on your own now!” Sure thing boss! If that’s the protocol, we will follow.

当您点击文本字段时,键盘会弹出,并允许您键入所需的任何内容。 现在,一旦完成写操作,就没有默认的完成按钮可以关闭键盘,在键盘外部轻按也不做任何事情。 就像iOS上说的那样-“我为您自动弹出键盘还不够吗? 想办法让它现在自己消失!” 肯定是老板! 如果是这样的协议,我们将遵循。

Moving text-fields on your screen when the Keyboard appears & disappears

当键盘出现或消失时,在屏幕上移动文本字段

Image for post

When your text-field is placed in the lower area of your screen like for example a chat application, you’ll come across this scenario — You tap on it and the keyboard appears and your text-field should move upwards along with the keyboard. This does not happen by default on iOS! What happens is — when you tap on the text-field, the keyboard sure appears, but now your text-field is no longer visible! The keyboard just overlaps the text-field on the screen that was placed near the bottom of the screen. Yes, you heard it right! iOS won’t automatically shift the text-field as per the keyboard.

当您将文本字段放置在屏幕的下部(例如,聊天应用程序)时,您会遇到这种情况-点击它,出现键盘,并且文本字段应与键盘一起向上移动。 默认情况下,iOS不会发生这种情况! 发生的是-当您点击文本字段时,肯定会出现键盘,但是现在您的文本字段不再可见! 键盘与位于屏幕底部附近的屏幕上的文本字段重叠。 是的,您没听错! iOS不会根据键盘自动移动文本字段。

When I was a beginner in iOS development, this issue caught me by surprise! Mainly because I code in Android too and this behavior is handled very gracefully by default over there. Never knew something as simple as a keyboard would have to be handled manually.

当我还是iOS开发的初学者时,这个问题让我感到惊讶! 主要是因为我也使用Android编写代码,并且默认情况下该行为的处理非常优美。 从来没有人知道像键盘这样的简单操作必须手动处理。

Enough of complaints. Where there is a problem, there ought to be a solution. Our jobs as engineers and developers are to find answers to problems like this and solve them elegantly. There are a lot of ways in which people have already solved this problem. For now, I’ll be walking you through the findings and solutions that I use in my day to day projects.

投诉足够了。 哪里有问题,应该有一个解决方案。 我们作为工程师和开发人员的工作是寻找此类问题的答案并优雅地解决它们。 人们已经用很多方法解决了这个问题。 现在,我将向您介绍我在日常项目中使用的发现和解决方案。

问题1 —处理键盘被解雇(如何使该键盘消失?) (Problem 1 — Handling Keyboard dismissal (How do I make this Keyboard go away?))

Like we were discussing above, keyboards in iOS don’t disappear on its own. The return key on the keyboard does nothing by default! Also, there is no return key for Numeric Keypad! Tapping outside the keyboard area also does not make that thing go away! Whhattt???

就像我们上面讨论的那样,iOS中的键盘不会自行消失。 默认情况下,键盘上的回车键不执行任何操作! 此外,数字键盘没有返回键! 在键盘区域之外点击也不会使那东西消失! Whhattt ???

Unfortunately, Apple has not yet made the dismissal of the keyboard a default thing. Hence we developers need to handle this scenario programmatically in our app. Fortunately, there are several ways in which we can achieve this functionality and that too within a few lines of code. Which way to implement in your code may depend on your exact scenario. You can judge the best one and use the same as per your requirement.

不幸的是,苹果尚未将解雇键盘作为默认操作。 因此,我们的开发人员需要在我们的应用中以编程方式处理这种情况。 幸运的是,在几行代码中,我们可以通过多种方式来实现此功能。 在代码中实现哪种方式可能取决于您的实际情况。 您可以判断最佳选择,并根据需要使用最佳选择。

通过点击手势- (Via Tap Gesture -)

This is the quickest way to implement keyboard dismissal. Just set a Tap gesture on the main View and hook that gesture with a function which calls view.endEditing .

这是实现键盘关闭的最快方法。 只需在主View上设置一个Tap手势,然后使用调用view.endEditing的函数将该手势挂接即可。

Apple docs say the below about endEditing -

苹果文档说以下有关endEditing的内容-

  • Causes the view (or one of its embedded text fields) to resign the first responder status.

    使视图(或其嵌入式文本字段之一)退出第一响应者状态。

That’s it! Now when you tap on a text-field and keyboard appears, just tap outside anywhere on the view and your keyboard would be dismissed.

而已! 现在,当您点击文本字段并出现键盘时,只需在视图上的任意位置点击外部,键盘便会消失。

Image for post

The below code can be shortened into just 2 lines but I have specifically broken into functions to help make this clear as possible. I have also added comments in the code to help understand what each function does.

下面的代码可以缩短为两行,但我专门细分了一些功能,以使这一点尽可能清楚。 我还在代码中添加了注释,以帮助理解每个函数的功能。

KeyboardHandlingViaTapGesture.swift
KeyboardHandlingViaTapGesture.swift

通过键盘返回键- (Via Keyboard Return Key -)

Image for post

Another great option is to use that non-functional keyboard Return/Done/Continue key. It’s just sitting there doing nothing unless we have specified some custom behavior in textFieldShouldReturn function.

另一个不错的选择是使用该非功能键盘的Return / Done / Continue键。 除非我们在textFieldShouldReturn函数中指定了一些自定义行为,否则它只是坐在那里什么也不做。

textFieldShouldReturn Asks the delegate if the text field should process the pressing of the return button.

textFieldShouldReturn 询问委托人文本字段是否应处理返回按钮的按下。

  • Here you would first have to set the delegates for the text-fields.

    在这里,您首先必须为文本字段设置委托。
  • Set Tag to the text-fields. What is a Tag, you ask? Apple documentation says — An integer that you can use to identify view objects in your application. The setting of Tag is optional and would not be required when you have only 1 text-field. But here I am assigning Tag to the text-fields by incrementing their value by 1 and in the order, they are placed on the screen. This would help us identify the text-fields in code.

    将“标签”设置为文本字段。 您问什么是标签? Apple文档说:— 一个整数,可用于标识应用程序中的视图对象 。 标签的设置是可选的,只有一个文本字段时不需要设置。 但是在这里,我通过将文本字段的值增加1并将它们分配到屏幕上的顺序来为文本字段分配Tag。 这将有助于我们识别代码中的文本字段。

  • textFieldShouldReturn fires when the user presses the Return key on the keyboard. Hence, here we check — Is there any other text-field in the view whose tag is +1 greater than the current text-field on which the return key was pressed. If yes → then move the cursor to that next text-field. If No → Dismiss the keyboard

    当用户按下键盘上的Return键时,将触发textFieldShouldReturn。 因此,我们在这里检查-视图中是否存在其他任何文本字段,其标记比按了回车键的当前文本字段大+1。 如果是→,则将光标移至下一个文本字段。 如果否→关闭键盘

Also don’t worry about that password field not visible when typing. We’ll solve that issue when we discuss about moving text-fields to visibility as per the keyboard in the later section of this article.

也不必担心键入时看不到密码字段。 当我们讨论按照本文后面部分中的键盘将文本字段移动到可见性时,将解决该问题。

KeyboardHandlingViaReturnKey.swift
KeyboardHandlingViaReturnKey.swift

通过数字键盘的工具栏- (Via Toolbar for Number Pad -)

Image for post

The above solution with textFieldShouldReturn works great but unfortunately, there is no “Return” key on iOS Number Pad. To overcome our barrier here in the case of Number Pad, we can add a simple Toolbar above our Keyboard with a “Done” button. This “Done” button is going to call the same function we used in our Tap Gesture Method above and would dismiss our keyboard. To keep consistency across the fields, you can use Toolbars across the app as a common patter to dismiss your keyboard.

上面的带有textFieldShouldReturn的解决方案效果很好,但不幸的是,iOS Number Pad上没有“ Return”键。 为了克服数字键盘的障碍,我们可以在键盘上方添加一个简单的工具栏,并带有“完成”按钮。 此“完成”按钮将调用与我们上面的“点击手势”方法中使用的功能相同的功能,并将关闭键盘。 为了保持各个字段的一致性,您可以在整个应用程序中使用工具栏来关闭键盘。

KeyboardHandlingViaToolBar.swift
KeyboardHandlingViaToolBar.swift

I found a nice article about extension for creating Done Button Toolbar which will help you reduce the code duplication and hook the same function across the app -

我找到了一篇有关创建Done Button Toolbar扩展的不错的文章,它将帮助您减少代码重复并在应用程序中挂钩相同的功能-

SWIFT — Add keyboard Done button using UIToolbar

SWIFT-使用UIToolbar添加键盘完成按钮

If you need more insights & ways on dealing with Keyboard dismissal, I found this great article on medium, You can find it here -

如果您需要更多有关键盘解雇的见解和方法,我在媒体上找到了这篇很棒的文章,您可以在这里找到-

Best way to dismiss Keyboard in a View Controller iOS (Swift)

在View Controller iOS(Swift)中关闭键盘的最佳方法

问题2 –按键盘移动文本字段(我的文本字段在哪里?) (Problem 2 — Moving text-fields as per the keyboard (Where is my text-field?))

We need to see our text while typing, that’s basic UX. Unfortunately, when your text-field is placed at the bottom area of your screen like for example in a chat application, your keyboard is going to overlap it as soon as you tap on the field. We need to handle this programmatically beforehand.

我们需要在键入时查看文本,这是基本的UX。 不幸的是,当您将文本字段放置在屏幕的底部(例如在聊天应用程序中)时,只要您点击该字段,键盘就会与它重叠。 我们需要预先以编程方式处理此问题。

What is our expected behavior here?

我们在这里的预期行为是什么?

Image for post

First, we need to check whenever a field is tapped and the keyboard appears, whether the keyboard is going to overlap the field (which in our chat application’s case, it will)? If so → scroll the view such that your text-field appears just above the keyboard. If your text-field is not overlapped by the keyboard, then there is no need to shift/scroll the screen.

首先,我们需要检查何时轻按一个字段并出现键盘,键盘是否会与该字段重叠(在我们的聊天应用程序的情况下,它将重叠)? 如果是这样,→滚动视图,使您的文本字段出现在键盘上方。 如果您的文本字段没有被键盘覆盖,则无需移动/滚动屏幕。

Enough about the problem, let’s take a deep dive into the solution. I have added comments in the below code to help in better understanding the role of each function in achieving our desired goal.

足以解决这个问题,让我们深入研究该解决方案。 我在下面的代码中添加了注释,以帮助更好地理解每个功能在实现我们期望的目标中的作用。

KeyboardHandlingWithTextfields.swift
KeyboardHandlingWithTextfields.swift

问题3 —代码重复 (Problem 3 — Repetition of code)

We would most probably have multiple text-field in our Applications. And these text-fields would be scattered across our entire application on different Screens. The above solution we implemented was in single ViewController. So how do we go about implementing these solutions in all the ViewControllers wherever we need to handle our Keyboard?

我们很可能在我们的应用程序中有多个文本字段。 这些文本字段将分散在整个应用程序的不同屏幕上。 我们实现的上述解决方案在单个ViewController中。 那么,我们该如何在需要处理键盘的所有ViewController中实现这些解决方案?

The first thing that would come to our minds is to add the above code snippets in all the ViewControllers wherever we need to handle such scenarios. But that means we would have to keep manually adding this code in every ViewController. There has to be a better way!

我们想到的第一件事是在需要处理此类场景的所有ViewController中添加以上代码片段。 但这意味着我们必须继续在每个ViewController中手动添加此代码。 一定有更好的方法!

Thankfully, there is! We would be using some basic concept of OOP over here — Inheritance. We would be declaring a base keyboard handling class which would be inherited from our default UIViewController. Now wherever we need to handle our keyboard, we would just inherit our class from our base class.

幸运的是,有! 在这里,我们将使用OOP的一些基本概念-继承。 我们将声明一个基本的键盘处理类,该类将从默认的UIViewController继承。 现在,无论何时需要处理键盘,我们都将从基类继承我们的类。

  • Declare a base class for handling keyboard

    声明用于处理键盘的基类
  • Write our entire keyboard handling code in that base class

    在该基类中编写整个键盘处理代码
  • Inherit your ViewControllers from this base class and Voila! You have handled your keyboard issues elegantly.

    从该基类和Voila继承您的ViewController! 您已经很好地处理了键盘问题。

We’ll see how this looks in code -

我们将在代码中看到它的外观-

KeyboardHandlingBaseVC.swift
KeyboardHandlingBaseVC.swift

奖金-让我们看一些图书馆 (Bonus — Let’s see some Libraries)

So let’s say you don’t want to handle any of the issues mentioned above manually. There may be various reasons for that but yeah the possibility exists. It’s fine, sometimes time is of great essence. Don’t worry, we have got that aspect also covered in this article. There are various libraries out there that solve the Keyboard Dismissal and TextField handling problem. I’ll list down a couple so that you can go through their read-me and find for yourself whichever suits your needs.

因此,假设您不想手动处理上述任何问题。 可能有多种原因,但是是的,存在这种可能性。 很好,有时时间很重要。 不用担心,本文也涵盖了这一方面。 有各种各样的库可以解决键盘解雇和TextField处理问题。 我将列出几对,以便您可以阅读他们的自述文件,并自己找到适合您需要的内容。

结论 (Conclusion)

So far we explored the problem of keyboard dismissal & TextField handling with keyboard. We also explored some of the ways in which we can easily solve these problems along with avoiding code repetition in our project. There is no such good or bad way when it comes to solving a technical problem. What matters the most is — At that particular moment, what works for you? what works for the project? what works for your team? There may be times when you would need to use a mix of the above techniques or sometimes one single pattern can be followed across the app! At the end of the day what matters is that you solved the problem :)

到目前为止,我们探讨了键盘解雇和使用键盘处理TextField的问题。 我们还探索了一些可以轻松解决这些问题以及避免在项目中重复代码的方法。 解决技术问题没有好的方法。 最重要的是-在那个特定时刻,什么对您有用? 什么适合该项目? 什么对您的团队有效? 有时您可能需要混合使用以上技术,有时在整个应用程序中可能会遵循一个单一模式! 归根结底,重要的是您解决了问题:)

That’s all from this article, do share if you all have any other ideas & approaches to solve this particular problem. I would be happy to discuss the same!

这就是本文的全部内容,如果您还有其他解决此特定问题的想法和方法,请分享。 我很乐意讨论同样的问题!

If you enjoyed reading this article and learned something, share it amongst your developer friends/colleagues and spread the knowledge! If you have anything to discuss regarding Keyboard Handling or any other topic related to Mobile Apps, Development, Designing, Engineering… Drop a comment below or DM me on Twitter :)

如果您喜欢阅读本文并学到了一些东西,请与您的开发人员朋友/同事分享并传播知识! 如果您有任何关于键盘处理或任何其他与移动应用程序,开发,设计,工程相关的话题的讨论,请在下面发表评论,或在 Twitter上与 我联系 :)

If you find this interesting, chances are you’ll find my twitter feed too! I keep sharing articles and stuff related to development, design and productivity on a daily basis. So hop on, follow me on Twitter and enjoy the learning ride!

如果您发现这个有趣,那么您也可能会找到我的Twitter提要! 我每天都会分享与开发,设计和生产力相关的文章和内容。 因此,跳上,在 Twitter 上关注我 ,享受学习之旅!

Till the next Article…

直到下一篇文章...

翻译自: https://medium.com/flawless-app-stories/keyboard-handling-in-ios-swift-5-8b60d602a8f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值