【问题标题】:Is there a delegate call for when the text is changed on a UITextView?在 UITextView 上更改文本时是否有委托调用?
【发布时间】:2014-10-21 16:29:38
【问题描述】:

当我像这样以编程方式设置我的UITextView 时:

[self.textView setText:@""];

委托方法textViewDidChange: 没有被调用。有没有办法让我创建一个UITextView 子类?

【问题讨论】:

标签: ios cocoa-touch uitextview uitextviewdelegate


【解决方案1】:

使用代码手动设置UITextView 的文本时,不会调用textViewDidChange: 方法。 (如果你设置了文本视图的delegate,那么它会在用户编辑它时被调用。)

一种可能的解决方法是在您编辑文本时手动调用textViewDidChange:。例如:

[self.textView setText:@""];
[self textViewDidChange:self.textView];

有点老套的做法,但它可以完成工作。

【讨论】:

  • 这是一种有趣的方法。大多数情况下,人们不会考虑手动调用框架的委托方法。不过,这是个好主意。
  • 绝对不是 hackish,IMO。方法应该被调用,而这个方法正盯着你。
【解决方案2】:

我赞成@rebello95 的回复,因为这是一种方法。但另一种不那么老套的方法是这样做

-(void)whereIManuallyChangeTextView
{//you don't actually have to create this method. It's simply wherever you are setting the textview to empty
  [self.textView setText:@""];
  [self respondToChangeInTextView:self.textView];
}

- (void)textViewDidChange:(UITextView *)textView
{
  //...some work and then
  [self respondToChangeInTextView:textView];
}

-(void)respondToChangeInTextView:(UITextView *)textView
{
  //what you want to happen when you programmatically/manually or interactively change the textview
}

这个 sn-p 举例说明了一种可敬的模式,它将使您的代码更具可读性。

【讨论】:

    【解决方案3】:

    你可以快速覆盖 UITextView 类中的文本变量

    class MyTextView: UITextView {
    
        override public var text: String? {
            didSet {
                self.textViewDidChange(self)
            }
        }
    
    }
    

    【讨论】:

    • 这行不通,因为在用户输入时它不会被调用
    • 它应该只增强文本视图以在通过代码@LucasChwe 更改文本时调用委托
    【解决方案4】:

    旧帖子,但我遇到了同样的问题,并认为我会分享我的解决方案(在 Swift 中)。

    textViewDidChange(_ textView: UITextView) 不会通过仅设置 text 属性来调用,但会在使用 replace(range: UITextRange, withText: String) 时调用。所以你需要为 UITextView 的整个字符串创建一个 UITextRange 并用一个新的字符串替换它。

        // Create a range of entire string
        let textRange = textView.textRange(from: textView.beginningOfDocument, to: textView.endOfDocument)
        // Create a new string
        let newText = ""
        // Call Replace the string in your textview with the new string
        textView.replace(textRange!, withText: newText)
    

    应该这样做。当然,您需要设置 UITextViewDelegate 才能使其工作:

    class ViewController: UIViewController, UITextViewDelegate {
    

    【讨论】:

    • 试过了,但使用 textView.replace 不会为我调用委托
    【解决方案5】:

    你也可以继承 UITextView 并覆盖 setText 以包含

    [self textViewDidChange:self.textView]

    这样您就不必每次设置 UITextView 的文本时都调用它。

    【讨论】:

      【解决方案6】:

      委托方法textDidChange不响应文本中的程序更改,您可以使用观察来获得通知

      1. @objc dynamic声明你的文本视图变量
      2. 声明并保存一个类型为NSKeyValueObservation的变量
      3. 使用函数observe(_:changeHandler:)绑定你的文本视图的文本属性,用步骤2中声明的变量保存返回值
      4. 观察changeHandler的变化

      示例:

      @objc dynamic private var textView: UITextView!
      private var observation: NSKeyValueObservation?
      
      func bind() {
          observation = observe(\.textView.text, options: [.old, .new]) { object, change in
              print(object, change)
          }
      }
      

      【讨论】:

        【解决方案7】:

        改用这个:(这不会重置当前文本

        [self.textView insertText:@"something"];
        

        这将调用委托并在光标所在的位置添加文本。当然,如果您想重置整个文本,您可以:

        [self.textView setText:@""];
        [self textViewDidChange:self.textView];
        

        [self.textView setText:@""];
        [self.textView insertText:@"something"];
        

        【讨论】:

        猜你喜欢
        • 2012-08-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-28
        • 1970-01-01
        • 2019-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多