In this tutorial, we’ll be discussing the UITextView element and implement the various forms of it in our application.
在本教程中,我们将讨论UITextView元素,并在我们的应用程序中实现它的各种形式。
Unlike its name, a UITextView is not just a text view. You can edit it, type in it, scroll it.
A UITextView is a multiline text region. It has a built-in UIScrollView.
与它的名称不同,UITextView不仅仅是文本视图。 您可以对其进行编辑,键入,滚动。
UITextView是多行文本区域。 它具有内置的UIScrollView 。
By default a UITextView is editable. To disabled editing you need to set the property isEditable
as false
.
默认情况下,UITextView是可编辑的。 要禁用编辑,您需要将isEditable
属性isEditable
为false
。
To create it programmatically you need to create a rectangle with a width and height specified:
要以编程方式创建它,您需要创建一个指定宽度和高度的矩形:
let uiTextView = UITextView()
uiTextView.frame = CGRect(x: 0, y: 0, width: 200, height: 150)
UITextView does not provide a placeholder/hint text by default.
默认情况下,UITextView不提供占位符/提示文本。
The UITextViewDelegate protocol defines a set of optional methods that gets triggered when the text is being edited. All the protocol methods are optional.
UITextViewDelegate协议定义了一组可选方法,这些方法在编辑文本时触发。 所有协议方法都是可选的。
Following are some of the methods present in the UITextViewDelegate.
以下是UITextViewDelegate中提供的一些方法。
textViewDidBeginEditing
/textViewWillBeginEditing
textViewDidEndEditing
/textViewWillEndEditing
textViewDidChange
– Gets called when the text is editted.
textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String)
– This returns a boolean which asks if the text should be replaced or not.
textViewDidBeginEditing
/ textViewWillBeginEditing
textViewDidEndEditing
/ textViewWillEndEditing
textViewDidChange
–编辑文本时调用。
textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String)
–这将返回一个布尔值,询问是否应替换该文本。
An interesting use case would be to set the character limit on the UITextView:
一个有趣的用例是在UITextView上设置字符限制:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText newText: String) -> Bool {
return textView.text.count + (newText.count - range.length) <= 140
}
This sets the character limit to 140. Just like twitter!
这将字符数限制设置为140。就像Twitter!
Enough talk. Lets code!
聊够了。 让代码!
Create a new XCode project and let’s get started:
创建一个新的XCode项目,让我们开始吧:
In the Main.storyboard drag the UITextView onto the ViewController and do the following instructions:
在Main.storyboard中,将UITextView拖到ViewController上,并执行以下说明:
.
。
On running the application on the simulator and device we get:
在模拟器和设备上运行应用程序后,我们得到:
That’s WEIRD!
那真是怪了!
The keyboard pops up over the UITextView.
On clicking return, the keyboard is getting dismissed.
键盘弹出UITextView上方。
单击返回时,键盘将关闭。
We need to fix these.
我们需要解决这些问题。
Add the following code in your ViewController.swift file:
在您的ViewController.swift文件中添加以下代码:
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var bottomTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
bottomTextView.delegate = self
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateTextView(notification:)), name: Notification.Name.UIKeyboardWillChangeFrame, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateTextView(notification:)), name: Notification.Name.UIKeyboardWillHide, object: nil)
}
func textViewDidBeginEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.lightGray
}
func textViewDidEndEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.white
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
@objc func updateTextView(notification: Notification)
{
if let userInfo = notification.userInfo
{
let keyboardFrameScreenCoordinates = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let keyboardFrame = self.view.convert(keyboardFrameScreenCoordinates, to: view.window)
if notification.name == Notification.Name.UIKeyboardWillHide{
view.frame.origin.y = 0
}
else{
view.frame.origin.y = -keyboardFrame.height
}
}
}
}
In the above code, we’ve implemented the UITextViewDelegate Protocol, implemented keyboard dismiss logic and moved the UITextView above the keyboard.
在上面的代码中,我们已经实现了UITextViewDelegate协议,实现了键盘关闭逻辑,并将UITextView移到了键盘上方。
bottomTextView.delegate = self
要在UITextView上进行设置,请执行以下操作: bottomTextView.delegate = self
textViewDidBeginEditing
, textViewDidEndEditing
, textView(shouldChangeTextIn:)
. We change the background color of the UITextView when editting begins and ends.
resignFirstResponder()
is used to dismiss the Keyboard. To do so on a UITextView we do:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
textViewDidBeginEditing
, textViewDidEndEditing
, textView(shouldChangeTextIn:)
。 在编辑开始和结束时,我们更改UITextView的背景颜色。
resignFirstResponder()
用于关闭键盘。 为此,我们在UITextView上执行以下操作:
updateTextView
. 在viewDidLoad中,我们添加了两个Notification观察器,它们可检测Keyboard中的更改并触发功能updateTextView
。 updateTextView
we change the position of the UITextView depending on the notification name. 在updateTextView
内部,我们根据通知名称更改UITextView的位置。 The output when the application is now run is:
现在运行应用程序时的输出为:
Next, we’ll look into Auto-Sizing UITextViews
接下来,我们将研究自动调整UITextViews的大小
UITextViews size can be changed depending on the content size of it.
Let’s create another ViewController in our storyboard and connect it via a Button segue.
UITextViews的大小可以根据其内容大小进行更改。
让我们在情节提要中创建另一个ViewController,并通过Button segue进行连接。
In the SecondViewController.swift, we’ll add the UITextView programmatically and set the constraints through Swift Code as well.
在SecondViewController.swift中,我们将以编程方式添加UITextView并通过Swift代码设置约束。
In the below code, we’ve:
在下面的代码中,我们已经:
import UIKit
class SecondViewController: UIViewController, UITextViewDelegate {
let topTextView = UITextView()
override func viewDidLoad() {
super.viewDidLoad()
addAnotherTextView()
}
func addAnotherTextView() {
topTextView.delegate = self
topTextView.text = "Enter your notes here"
topTextView.frame = CGRect(x: 0, y: 0, width: 200, height: 150)
topTextView.font = .systemFont(ofSize: 20)
view.addSubview(topTextView)
topTextView.translatesAutoresizingMaskIntoConstraints = false
[
topTextView.topAnchor.constraint(equalTo: view!.safeAreaLayoutGuide.topAnchor),
topTextView.leadingAnchor.constraint(equalTo: view!.leadingAnchor),
topTextView.trailingAnchor.constraint(equalTo: view!.trailingAnchor),
topTextView.heightAnchor.constraint(equalToConstant: 40)
].forEach{
$0.isActive = true
}
}
func textViewDidBeginEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.lightGray
if (textView.text == "Enter your notes here")
{
textView.text = ""
textView.textColor = .black
}
}
func textViewDidEndEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.white
if (textView.text == "")
{
textView.text = "Enter your notes here"
textView.textColor = .lightGray
}
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
func textViewDidChange(_ textView: UITextView) {
let size = CGSize(width: view.frame.width, height: .infinity)
let approxSize = textView.sizeThatFits(size)
textView.constraints.forEach{(constraint) in
if constraint.firstAttribute == .height
{
constraint.constant = approxSize.height
}
}
}
}
textViewDidChange is a part of the UITextViewDelegate protocol. This gets triggered whenever text is added.
Each time we calculate the size of the text and increase the height constraint of the UITextView.
textViewDidChange是UITextViewDelegate协议的一部分。 每当添加文本时,都会触发该事件。
每次我们计算文本的大小并增加UITextView的高度限制。
The output of the application in action is:
实际应用程序的输出为:
As you can see the height of the UITextView is increased. But the UITextView keeps pushing the top line above.
如您所见,UITextView的高度增加了。 但是,UITextView一直将上方推到最上方。
This is because of the ScrollBars. We can disable them by adding the following line inside the addAnotherTextView() function:
这是由于ScrollBars。 我们可以通过在addAnotherTextView()函数中添加以下行来禁用它们:
topTextView.isScrollEnabled = false
Now the top line doesn’t keep going out of the screen.
现在,最上面的一行不会一直显示在屏幕之外。
Let’s look at another use case.
让我们看看另一个用例。
We can size the UITextView such that it can expand only to a specific height.
我们可以调整UITextView的大小,使其只能扩展到特定的高度。
Change your textViewDidChange function to:
将您的textViewDidChange函数更改为:
func textViewDidChange(_ textView: UITextView)
{
if topTextView.contentSize.height >= 120.0
{
topTextView.isScrollEnabled = true
}
else
{
let size = CGSize(width: view.frame.width, height: .infinity)
let approxSize = textView.sizeThatFits(size)
textView.constraints.forEach {(constraint) in
if constraint.firstAttribute == .height{
constraint.constant = approxSize.height
}
}
topTextView.isScrollEnabled = false
}
}
The logic is pretty simple:
逻辑很简单:
If it is, don’t increase the height anymore and just enable the scrolling.
If the max height isn’t reached, keep the scrollbars disabled.
如果是这样,请不要再增加高度,而只需启用滚动即可。
如果未达到最大高度,请禁用滚动条。
The output of the application in action is:
实际应用程序的输出为:
This brings an end to this tutorial on UITextView. We implement some practical scenarios that might help you in your iOS Development by using UITextViewDelegate and also Notification Observers.
这样就结束了本教程的UITextView。 我们使用UITextViewDelegate以及Notification Observers来实现一些实用的方案,这些方案可能会在您的iOS开发中为您提供帮助。
You can download the project from the link below:
您可以从下面的链接下载项目:
翻译自: https://www.journaldev.com/22238/ios-uitextview-and-uitextviewdelegate