如何知道文本何时粘贴到 UITextView 中?

问题描述 投票:0回答:12

将文本块粘贴到 UITextView 中时会触发什么事件?粘贴文本时我需要修改 textView 的框架。

ios uikit uitextview
12个回答
37
投票

这是我用来检测 UITextView 中的粘贴事件的方法:

 // Set this class to be the delegate of the UITextView. Now when a user will paste a text in that textview, this delegate will be called.
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    // Here we check if the replacement text is equal to the string we are currently holding in the paste board
    if ([text isEqualToString:[UIPasteboard generalPasteboard].string]) {

        // code to execute in case user is using paste

    } else {

        // code to execute other wise
    }

    return YES;
}

22
投票

如果粘贴板中有长句子,则通过

if string == UIPasteboard.general.string
检查粘贴板的字符串需要几秒钟。进行此检查时,用户会看到键盘被冻结。 我的解决办法是检查新字符的长度是否大于1。 如果它长于 1,则该字符串来自粘贴板。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if string.characters.count > 1{
            //User did copy & paste

        }else{
            //User did input by keypad
        }            
         return true
 }

19
投票

你的 UITextView 将调用它的 UITextViewDelegate 方法

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text

如果已设立代表。当在键盘上键入字符时以及将文本粘贴到文本视图中时都会调用此函数。粘贴的文本是 replacementText 参数。

请参阅 http://developer.apple.com/library/ios/#documentation/uikit/reference/UITextViewDelegate_Protocol/Reference/UITextViewDelegate.html#//apple_ref/occ/intf/UITextViewDelegate


8
投票

尝试子类化 UITextview,并重写此函数。

public override func paste(_ sender: Any?) 

7
投票

这在

中运行完美

Xcode 11x 迅捷 5x

 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text.contains(UIPasteboard.general.string ?? "") {
        return false
    }
    return true
}

当用户尝试粘贴到文本字段时,if条件将执行
此代码将停止粘贴


6
投票

适用于 Swift5.1

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let paste = UIPasteboard.general.string, text == paste {
       print("paste")
    } else {
       print("normal typing")
    }
    return true
}

6
投票
在很多情况下都可以调用

textView(_, shouldChangeTextIn, replacementText)
。如果您每次都会读取
UIPasteboard.general.string
值,用户将看到系统警报,表明应用程序在输入每个字母后访问了粘贴板。

为了避免这个问题,你可以创建 UITextView 的子类并覆盖其中的

paste(_)
函数。每次用户尝试粘贴内容时,系统都会调用此函数一次。

使用下一次调用

textView(_, shouldChangeTextIn, replacementText)
来处理粘贴事件。

var isPastingContent = false // helper variable

open override func paste(_ sender: Any?) {
    isPastingContent = true // next call of `shouldChangeTextIn` will be for the paste action
    super.paste(sender)
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if isPastingContent { // if we detected paste event
         // paste detected, do what you want here
         let pasteboardContent = UIPasteboard.general.string // you can get pasteboard content here safely. System alert will be shown only once.
         isPastingContent = false // toggle helper value back to false
    }
}

3
投票

carlos16196 是一个很好的方法,但我也会通过将

[text isEqualToString:[UIPasteboard generalPasteboard].string]
更改为
[text containsString:[UIPasteboard generalPasteboard].string]

来调整它

通过这样做,您将检测用户何时在文本视图中粘贴不在 UIPasteboard 中的其他键入文本之后。

这是代码:

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

// Here we check if the replacement text is equal to the string we are currently holding in the paste board
if ([text containsString:[UIPasteboard generalPasteboard].string]) {

    // code to execute in case user is using paste

} else {

    // code to execute other wise
}

return YES;
}

2
投票

iOS 13 与

Combine

public extension UITextView {
    var textDidChangePublisher: AnyPublisher<String, Never> {
        NotificationCenter.default
            .publisher(for: UITextView.textDidChangeNotification, object: self)
            .compactMap { $0.object as? UITextView }
            .compactMap(\.text)
            .eraseToAnyPublisher()
    }
    
    var attributedTextDidChangePublisher: AnyPublisher<NSAttributedString, Never> {
        NotificationCenter.default
            .publisher(for: UITextView.textDidChangeNotification, object: self)
            .compactMap { $0.object as? UITextView }
            .compactMap(\.attributedText)
            .eraseToAnyPublisher()
    }
}
var cancellable = Set<AnyCancellable>()

textView.textDidChangePublisher
    .removeDuplicates()
    .sink { [weak self] newValue in
        guard let self = self else { return }
        // what you want
    }
    .store(in: &cancellable)

1
投票

这是我能够让它发挥作用的唯一方法。我使用了文本字段,但相同的概念仍然适用于文本视图。

在下面的

shouldChangeCharactersIn
委托方法中,我将
string
参数转换为 NSString,然后又转换回 String。然后我将它与粘贴的任何内容进行比较。其他所有内容都在代码上方的注释中。

// 1. class property for anything that was copied and will be pasted
var pasted: String?

// 2. When the user first taps the textfield set the above class property to the copied text (if there is any)
func textFieldDidBeginEditing(_ textField: UITextField) {

    // 3. set it here
    pasted = UIPasteboard.general.string // this is what was copied and will be pasted
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    guard let safeText = textField.text else { return true }

    let currentString: NSString = safeText as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString

    let str = newString as String

    // 4. compare the above str constant to the pasted variable
    if str == self.pasted {
        print("pasted")

    } else {

        print("typed")
    }

    return true
}

func textFieldDidEndEditing(_ textField: UITextField) {

    // 5. when the user is finished with the textField set the pasted property to nil
    pasted = nil
}

0
投票

这就是我用来检测粘贴图像的方法:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if (UIPasteboard.generalPasteboard.image &&
        [UIPasteboard.generalPasteboard.string.lowercaseString isEqualToString:text.lowercaseString]) {

       //Pasted image

        return NO;
    }

    return YES;
}

-2
投票

在 SWIFT 4 中:

func textViewDidChange(_ textView: UITextView) {

    if(textView.text == UIPasteboard.general.string)
    {
        //Text pasted
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.