Let’s Copy A UITextField With A Touch!

I created an app that pulls data from an open API, which is simply a collection of open APIs.

I had previously found a roundabout way to disable the option to modify the text but still pop up the option to copy. It worked, but it looked silly. Now, I could have instead implemented an SFSafariViewController, but I went with copying. Either way though, I’d need to be able to trigger an action upon touch.

The problem was that when I googled the problem I found conflicting information. Some people tried adding on tap gesture recognizers. Of those, some said it worked and others said it didn’t. People then responded to the former saying that if it does work, it shouldn’t and you shouldn’t do it.

I finally found what I was looking for, so let’s dive in.

Step 1: Conform to the UITextFieldDelegate protocol.

extension MyView : UITextFieldDelegate {

}

Now, I have 5 UITextFields on this view but I only need to copy the text of one when it is touched, so I make sure to set that UITextField’s delegate:

        link.delegate = self

What this says is “Listen up, if and only if this specific textField would trigger any of the optional methods I implement from the UITextFieldDelegate protocol, run those methods please”.

Note: If you forget to add conformance, you’ll see:

Cannot assign value of type ‘YourView’ to type ‘UITextFieldDelegate?’

And if you forget to set the textField’s delegate to self, you’ll notice that nothing happens no matter how hard you wish it would.

Step 2: Find the right method

Now that you’re able to use a new set of methods relating to the UITextField, they’ll show up if you start typing (assuming Xcode isn’t being disagreeable). The one you’re specifically looking for here is textFieldShouldBeginEditing. To quote the documentation:

The text field calls this method when the user performs an action that would normally initiate the editing of the text field’s text. Implement this method if you want to prevent editing from happening in some situations. For example, you could use this method to prevent the user from editing the text field’s contents more than once. Most of the time, you should return true to allow editing to proceed.

Yes, normally we would want to return true; however, this is not a normal time.

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        print("Testing... testing.. is this thing on?"
        return false
    }

If you leave it like this and run the app, you’ll notice that nothing happens in the view when you touch that textField but you should notice that printed statement show up in Xcode. Yay for progress!

Step 3: Add the copy function!

Now that we have a method being called whenever we touch that textField and we have removed the option to edit the text (so no keyboard popup!), we just need to add the clipboard copy part and we’ll be done.

You can set up a pasteboard variable within your view like this:

let pasteboard = UIPasteboard.general

And then within your newly added method:

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        pasteboard.string = link.text
        return false
    }

This copies the textField’s text to the iOS device’s clipboard.

Now, I also added a quick popup to inform the user that the text was copied so that they know what’s happening, but a quick popup view is the subject of another blog post.