UITextView粘贴方法重写

发布于 2024-08-22 15:11:23 字数 152 浏览 5 评论 0原文

我真的希望能够检测 UITextView 中的粘贴事件,但似乎无法做到这一点。

我最初尝试对 UITextView 进行子类化并覆盖 Paste: 方法,但它永远不会在粘贴事件中被调用。

有人能够做到这一点吗?上一个类似的问题在八月份没有得到答案......

I really want to be able to detect a paste event in a UITextView, however it appears this cannot be done.

I originally tried subclassing a UITextView and overriding the paste: method, but it never gets called on a paste event.

Has anyone been able to do this? A previous question on the same ilk didn't have an answer back in August...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倥絔 2024-08-29 15:11:23

文本视图不会捕获 paste: 事件,因为它不是实际的响应者,也不是文本视图,而是为文本视图提供支持的私有 Web 视图 (UIWebDocumentView)。

但是,在粘贴时,Web 视图将调用文本视图的(私有)-[UITextView KeyboardInput:shouldInsertText:isMarkedText:],然后调用文本视图的委托的 -textView:shouldChangeTextInRange:替换文本:

因此,您只需在文本视图的委托中实现 -textView:shouldChangeTextInRange:replacementText: 即可。

(当然,正常的键盘输入也会触发该方法,目前还没有完美的区分方法。)

The text view doesn't catch the paste: event because it wasn't the actual responder is not the text view, but the private web view (UIWebDocumentView) that powers the text view.

However, on paste, the web view will call the text view's (private) -[UITextView keyboardInput:shouldInsertText:isMarkedText:], and in turn, the text view's delegate's -textView:shouldChangeTextInRange:replacementText:.

Therefore, you just need to implement -textView:shouldChangeTextInRange:replacementText: in the text view's delegate.

(Of course, normal keyboard input will trigger this method too. There's no perfect way to distinguish them.)

如果没有你 2024-08-29 15:11:23

@KennyTM 我为我的一个应用程序所做的就是跟上当前的文本长度和之前的文本长度。如果 (currentTextLength - previousTextLength) 大于 1,则用户一定粘贴了某些内容

@KennyTM what I did for one of my applications was keep up with the current text length and the previous text length. If the (currentTextLength - previousTextLength) was greater than 1, then the user must have pasted something

别念他 2024-08-29 15:11:23

使用 iOS 14,您必须分两部分执行此操作,以避免向用户显示您正在检查 UIPasteboard 的通知。就我而言,我不想对用户数据做任何不好的事情,但我确实想在用户粘贴到 UITextView 时进行一些特殊的格式化。

第 1 步: 创建自定义 UITextView 并覆盖 Paste()

import UIKit

protocol TouchableTextViewDelegate : class{
    func touchesDidBegin()
    func pasting()
}

class TouchableTextView: UITextView {
    weak var touchableDelegate : TouchableTextViewDelegate?

    
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if self.isFirstResponder{
            return true
        }
        touchableDelegate?.touchesDidBegin()
        return false
    }
    
    override func paste(_ sender: Any?) {
        touchableDelegate?.pasting()
        super.paste(sender)
    }
    
}

第 2 步: 在处理 shouldChangeTextIn 的文件位置中创建一个变量,并确保为该变量设置委托可触摸文本视图。在我的例子中

//top of the view
var isPasting : Bool = false

//also when creating UITextView use both delegates
textView.touchableDelegate = self
//add the normal delegate
textView.delegate = self

extension SliderTextView : TouchableTextViewDelegate{
    func pasting() {
        self.isPaste = true
    }
    
    func touchesDidBegin() {
        sliderEditingDelegate?.touchesDidBegin(sliderTextView: self)
    }
}

步骤3:在shouldChangeTextIn内部我处理这样的操作

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     let isPaste = self.isPaste
     //be sure to set this to false
     self.isPaste = false
     if isPaste,
        let pt = UIPasteboard.general.string,
        text.contains(pt){ 
        //you will see the paste notification and that is good for the user
        // but only when the user pastes
        // do whatever special thing or formatting you want to do

      }   
      return true
}

好处是除非用户在UITextView中粘贴,否则你不会触发通知。

With iOS 14 you have to do this in two parts to avoid showing the user notification that you are checking the UIPasteboard. In my case I did not want to do anything bad with the user data but I did want to do some special formating when the user did paste into the UITextView.

Step 1: Create a custom UITextView and override paste()

import UIKit

protocol TouchableTextViewDelegate : class{
    func touchesDidBegin()
    func pasting()
}

class TouchableTextView: UITextView {
    weak var touchableDelegate : TouchableTextViewDelegate?

    
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if self.isFirstResponder{
            return true
        }
        touchableDelegate?.touchesDidBegin()
        return false
    }
    
    override func paste(_ sender: Any?) {
        touchableDelegate?.pasting()
        super.paste(sender)
    }
    
}

Step 2: In the file location where you handle the shouldChangeTextIn create a variable and be sure to set the delegate for the TouchableTextView. In my case

//top of the view
var isPasting : Bool = false

//also when creating UITextView use both delegates
textView.touchableDelegate = self
//add the normal delegate
textView.delegate = self

extension SliderTextView : TouchableTextViewDelegate{
    func pasting() {
        self.isPaste = true
    }
    
    func touchesDidBegin() {
        sliderEditingDelegate?.touchesDidBegin(sliderTextView: self)
    }
}

Step 3: Inside shouldChangeTextIn I handle the action like this

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     let isPaste = self.isPaste
     //be sure to set this to false
     self.isPaste = false
     if isPaste,
        let pt = UIPasteboard.general.string,
        text.contains(pt){ 
        //you will see the paste notification and that is good for the user
        // but only when the user pastes
        // do whatever special thing or formatting you want to do

      }   
      return true
}

The good is that you will not trigger the notification unless the user is pasting in the UITextView.

み青杉依旧 2024-08-29 15:11:23

要检测用户是否正在解析 textView 中的文本,请将 shouldChangeTextInRange 委托中的 replacementText 与用户当前在 UIPasteboard 中保存的文本进行比较。然后根据要求采取行动。

有关代码,请参阅我在以下问题中的回答:

如何知道文本何时被粘贴到 UITextView

To detect if a user is parsing a text in a textView, compare the replacementText in the shouldChangeTextInRange delegate with the text the user is currently holding in the UIPasteboard. Then take action depending on requirements.

for code, see my answer in the following question:

how to know when text is pasted into UITextView

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文