快速检测 UILabel 文本更改

Posted

技术标签:

【中文标题】快速检测 UILabel 文本更改【英文标题】:Detect UILabel text change in swift 【发布时间】:2015-09-14 17:44:14 【问题描述】:

有没有办法在UILabel 的文本发生更改时收到通知,或者我最好使用UITextField 并将userInteractionEnabled 设置为false 并使用它的UIControlEditingChanged 事件实现我的目的?

例如。每次更改UILabel 的文本并相应地更改时,我都需要运行某些代码行。因此,我不想为每个案例编写几乎相似的 100 行代码,而是更改UILabel 的文本,我希望将它一起写在一个地方,并在每次更改UILabel 时调用它。我什至不知道这是否有意义。原谅我,我不能暴露太多代码。

【问题讨论】:

为什么需要这个?您正在显式调用someLabel.text = ...。所以你已经知道它正在改变。 嗯.. 只说几行代码 您需要使用您拥有的代码以及您想要的不同之处来更新您的问题。否则这不是很清楚。 好吧..不能真正暴露很多代码..我会看看我能做什么 但是为什么不直接调用一个函数,每次修改文本呢? 【参考方案1】:

创建一个继承自 UILabel 的类。如:

class YourLabel: UILabel 

    override var text: String? 
        didSet 
            if let text = text 
                println("Text changed.")
             else 
                println("Text not changed.")
            
        
    

为您的对象创建此类的出口。

@IBOutlet weak var label: YourLabel!
label.text = "abc"

【讨论】:

更新了我的答案。你可以检查一下。【参考方案2】:

斯威夫特 3

首先,在 UILabel 中添加一个观察者,获取关键路径 text

label.addObserver(self, forKeyPath: "text", options: [.old, .new], context: nil)

然后

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
  if keyPath == "text" 
    print("old:", change?[.oldKey])
    print("new:", change?[.newKey])
  

斯威夫特 2

label.addObserver(self, forKeyPath: "text", options: [.Old, .New], context: nil)

然后

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) 
    if keyPath == "text" 
        print("old:", change["old"])
        print("new:", change["new"])
    

控制台输出

例如控制台是:

old: Optional(<null>)
new: Optional(ABC)

【讨论】:

这确实有效。我已经在另一个答案中使用了它,因为可以从使用标签的同一个类中调用一个函数。 这是什么? atreat 的答案是软件的基础知识,你知道,它可以工作:) @Fattie 这是KVO(Key-Value Observing),didSet 正在使用它。 KVO 从 Objective-C 开始就有,可以进行更精细的控制。 当然——我只是在开玩笑,因为最新的 Swift 语法是最新的! :) 应该是正确答案。在我看来,与其继承 UILabel 只是为了观察 'didSet' 的变化,这是正确的方法。【参考方案3】:

您可以简单地使用 UILabel 的子类来做到这一点:

class Label : UILabel 
    override var text: String? 
        didSet 
            print("Text changed from \(oldValue) to \(text)")
        
    

oldValue 是 Swift 提供的一个特殊值。 见Property Observers

【讨论】:

【参考方案4】:

对于 Swift 3.2 及更高版本,首选方法是使用基于闭包的观察者:

@IBOutlet public weak var label: UILabel!

var textObserver: NSKeyValueObservation?

func someAppropriateFunction() 
  ...
  textObserver = label.observe(\.text)  [weak self] (label, observedChange) in
    self?.updateStuff()
  

闭包会将标签实例和NSKeyValueObservedChange 传递给您,其中包括以下属性:

  indexes: IndexSet?
  isPrior: Bool
  kind: NSKeyValueObservedChange<Value>.Kind
  newValue: Value?
  oldValue: Value?

【讨论】:

【参考方案5】:

斯威夫特 5

如果您想观察标签中的文字变化并制作动画。你需要创建子类 UILabel

class ObservedLabelAnimate: SpringLabel 

    override var text: String? 
        didSet 
            if let text = text 
                if oldValue != text 
                    animation = "fadeInLeft"
                    duration = 1.2
                    animate()
                
                print("This is oldvalue \(oldValue), and this is the new one \(text)")
            
        
    

对于这个例子,我将继承自 UILabel 的“SpringLabel”子类化

来自https://github.com/MengTo/Spring

基本上它会检查 oldValue 和 text (new one) 是否不同,然后会触发动画

使用方法:

@IBOutlet 弱变量标签:ObservedLabelAnimate!

【讨论】:

以上是关于快速检测 UILabel 文本更改的主要内容,如果未能解决你的问题,请参考以下文章

无法更改 UILabel 文本颜色

使更改 UILabel 文本不触发自动布局

在 UITableViewCell 内动画 UILabel 文本更改

无法更改 UILabel 的文本

UILabel - 如何更改文本位置

uilabel 文本更改后移动 uiview