简体   繁体   English

UITextView 数据变化 swift

[英]UITextView data change swift

How can you detect a change of data in a UITextView with Swift ?如何使用Swift检测UITextView中的数据变化? The following code does not do any detection.以下代码不做任何检测。

I am declaring the UITextView :我声明UITextView

@IBOutlet weak var bodyText: UITextView!

optional func textViewDidChange(_ textView: UITextView!) {
    println(bodyText.text)
}

Thanks Scott谢谢斯科特

You need to set UITextView delegate and implement textViewDidChange: method in it. 您需要设置UITextView 委托并在其中实现textViewDidChange:方法。 Unfortunately, I do not know if swift documentation is available online. 不幸的是,我不知道是否可以在线获得快速文档。 All the links go to the objective-c documentation. 所有链接都转到objective-c文档。

The code will look like this: ( updated for SWIFT 4.2 ) 代码如下所示:( 针对SWIFT 4.2更新

class ViewController: UIViewController, UITextViewDelegate { //If your class is not conforms to the UITextViewDelegate protocol you will not be able to set it as delegate to UITextView

    @IBOutlet weak var bodyText: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        bodyText.delegate = self //Without setting the delegate you won't be able to track UITextView events
    }

    func textViewDidChange(_ textView: UITextView) { //Handle the text changes here
        print(textView.text); //the textView parameter is the textView where text was changed
    }
}

Set delegate of UITextView .Refer UITextViewDelegate 设置UITextView delegate .Refer UITextViewDelegate

Write this in viewDidLoad viewDidLoad写下这个

bodyText!.delegate = self

For my case, I wanted the implementation to be independent from a UIViewController, so i dont need to assign a delegate just for text changes. 对于我的情况,我希望实现独立于UIViewController,所以我不需要为文本更改分配委托。 Or even maybe there is some kind of validation on the UITextView, and you wanna contain it per field instead of a delegate managing a lot of complicated logic. 或者甚至可能在UITextView上进行某种验证,并且您希望每个字段包含它而不是管理许多复杂逻辑的委托。

It requires to subclass UITextView, but its very much worth it imo: 它需要子类UITextView,但它非常值得imo:

class TextView: UITextView {

    convenience init() {
        self.init(frame: CGRect.zero, textContainer: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(textDidChangeNotification), name: UITextView.textDidChangeNotification , object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc func textDidChangeNotification(_ notif: Notification) {
        guard self == notif.object as? UITextView else {
            return
        }
        textDidChange()
    }

    func textDidChange() {
        // the text in the textview just changed, below goes the code for whatever you need to do given this event

        // or you can just set the textDidChangeHandler closure to execute every time the text changes, useful if you want to keep logic out of the class
        textDidChangeHandler?()
    }

    var textDidChangeHandler: (()->Void)?

}

For Swift 4: 对于Swift 4:

 func textViewDidChange(_ textView: UITextView) { // Your code here } 

For Swift 4.2, you can add UITextViewTextDidChange , UITextViewTextDidBeginEditing & UITextViewTextDidEndEditing notification observers to a UITextView like this:对于 Swift 4.2,您可以将UITextViewTextDidChangeUITextViewTextDidBeginEditingUITextViewTextDidEndEditing通知观察者添加到 UITextView,如下所示:

let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(textViewDidChange), name: NSNotification.Name.UITextViewTextDidChange , object: nil)
nc.addObserver(self, selector: #selector(textViewDidBeginEditing), name: NSNotification.Name.UITextViewTextDidBeginEditing , object: nil)
nc.addObserver(self, selector: #selector(textViewDidEndEditing), name: NSNotification.Name.UITextViewTextDidEndEditing , object: nil)

And the observers look like this:观察者看起来像这样:

@objc func textViewDidChange(_ notif: Notification) {
    guard notif.object is UITextView else { return }
    // Do something
}

@objc func textViewDidBeginEditing(_ notif: Notification) {
    guard notif.object is UITextView else { return }
    // Do something
}

@objc func textViewDidEndEditing(_ notif: Notification) {
    guard notif.object is UITextView else { return }
    // Do something
}

For Swift5, the format of the 'name' values are UITextView.textDidChangeNotification .对于 Swift5,“名称”值的格式是UITextView.textDidChangeNotification

When subclassing UITextView:子类化 UITextView 时:

import UIKit
class SelfAwareTextView: UITextView {
    
    func setup() {
        NotificationCenter.default.addObserver(self,
         selector: #selector(change),
         name: UITextView.textDidChangeNotification,
         object: self)
    }
    
    @objc func change(_ notif: Notification) {
        print("the user edited the text. It's now: " + text)
    }
}

In add observor, the object: is the sending object.在添加观察者中, object:是发送 object。

Somewhat confusingly, you set that to self since, in fact, we simply want notifications from ourself;有点令人困惑的是,您将其设置为self ,因为事实上,我们只是想要来自我们自己的通知; we don't care about other text views.我们不关心其他文本视图。

Regarding setup , recall that (in general) when subclassing a UITextView, you want to do setup in awakeFromNib rather than init, etc, since, among other issues you then catch any IBInspectable values.关于setup ,回想一下(通常)在子类化 UITextView 时,您希望在awakeFromNib而不是 init 等中进行设置,因为除其他问题外,您随后会捕获任何 IBInspectable 值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM