iOS13 Wrong UIPasteboard.general.changeCount after UITextField becomes first responder

I have an UIButton and a UITextField. When I press the button, the text field is made the first responder.

Here is the action for button press:


@objc func btnAction(_ sender: Any?) {

print("changeCount before pressing btn: \(UIPasteboard.general.changeCount)")

txtField.becomeFirstResponder()


DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {

print("changeCount after showing kbd: \(UIPasteboard.general.changeCount)")

}

}


When I press the button, the keyboard is shown and the changeCount of the general pasteboard is incremented by 2 even if I dont add anything to pasteboard!? Here's the output:

...

changeCount before pressing btn: 45

changeCount after showing kbd: 47

...


On iOS 11, 12, it works as expected, the changedCount is not modified.

Further on, I subclassed the UITextField like this:


class CustomTextField: UITextField {

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {

print("canPerformAction: \(action)")

let a = super.canPerformAction(action, withSender: sender)

print("changeCount after canPerformAction: \(UIPasteboard.general.changeCount)")

return a

}

}


The output is now:

...

changeCount before pressing btn: 45

canPerformAction: paste:

changeCount after canPerformAction: 46

changeCount after showing kbd: 47

...



On iOS 11, 12, 'canPerformAction' is not called at all:

...

changeCount before pressing btn: 3003

changeCount after showing kbd: 3003

...


It this a bug on iOS13 or am I doing something wrong?

Replies

Same problem here. Since iOS 13 the changeCount value is changing. Any updated on this?

I've also opened a bug report https://feedbackassistant.apple.com/feedback/7397122

I've opened a TSI for this and I got a solution:


When adding content on the pasteboard, beside the standard content type, (string, image, etc), also add a custom presentation type so you can check on it later.


let myContentKey = "myContent"

UIPasteboard.general.items = [[kUTTypeUTF8PlainText as String: someString, myContentKey: 1]]


And then, when pasting, do like this:


if (lastKnownGeneralPasteboardChangeCount != UIPasteboard.general.changeCount) &&

!UIPasteboard.general.contains(pasteboardTypes: [myContentKey])


{ // we'll be using this fresh content from the general pasteboard

//.....

}

else

{ // use app local pasteboard content, cause general pasteboard contains my own items

//.....

}

This is not a solution since I do not need to set the items. I just want to check if the user has copied another text with the pasteboard.

@myintruder do you have any updates about this?

  • No. The solution that I've described above works fine for me and I didn't research further.

Add a Comment