26

How does one copy the contents of a Text field to the iOS clipboard?

I have the following code & want to replace the "print(..)" statement with a statement that copies the content of the text field to the iOS clipboard.

Text(self.BLEinfo.sendRcvLog)
    .onTapGesture(count: 2) {
        print("Copy text field content to ClipBoard Here..")
    }

Can't seem to find any SwiftUI examples how to do this.

Thanks!

Gerard
  • 1,807
  • 4
  • 13
  • 20

4 Answers4

34

Use the following - put shown text into pasteboard for specific type (and you can set as many values and types as needed)

Update: for Xcode 13+, because of "'kUTTypePlainText' was deprecated in iOS 15.0..." warning

import UniformTypeIdentifiers

Text(self.BLEinfo.sendRcvLog)
    .onTapGesture(count: 2) {
        UIPasteboard.general.setValue(self.BLEinfo.sendRcvLog,
            forPasteboardType: UTType.plainText.identifier)
    }

for older versions:

import MobileCoreServices // << for UTI types

// ... other code

Text(self.BLEinfo.sendRcvLog)
    .onTapGesture(count: 2) {
        UIPasteboard.general.setValue(self.BLEinfo.sendRcvLog, 
            forPasteboardType: kUTTypePlainText as String)
    }
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Thanks for the fast response Asperi BUT the text seems to be copied to the clipboard in a non-text format. When I paste it from the clipboard (for example in iOS 'Notes' app), it just displays some hex sequence. So the text is getting pasted to clipboard but it seems to have some encoding issue? Any idea how to fix that (maybe use a different Text "Type")? – Gerard May 13 '20 at 11:11
  • OK - changed the type to "kUTTypePlainText" and it works like a charm! So if you can change your answer to that type I will mark it as correct answer! Thanks - MUCH APPRECIATED! – Gerard May 13 '20 at 11:20
25
Text(self.BLEinfo.sendRcvLog)
    .onTapGesture(count: 2) {    
        UIPasteboard.general.string = self.BLEinfo.sendRcvLog
    }

or really fancy:

Text(self.BLEinfo.sendRcvLog)
    .contextMenu {
        Button(action: {
            UIPasteboard.general.string = self.BLEinfo.sendRcvLog
        }) {
            Text("Copy to clipboard")
            Image(systemName: "doc.on.doc")
        }
     }
Zappel
  • 1,612
  • 1
  • 22
  • 37
11

For iOS 14+

UIPasteboard.general.setValue(message, forPasteboardType: "public.plain-text")
Chat Dp
  • 555
  • 5
  • 15
  • 2
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 15 '21 at 11:27
  • 2
    This should be the accepted answer. The [currently accepted answer](https://stackoverflow.com/a/61772472/1751073) does not compile in XCode 13. – blueberries Feb 15 '22 at 01:42
  • The only one that worked for me – Chris Neve Dec 31 '22 at 09:40
1

Here is a pretty good example for iOS only

import SwiftUI
import UniformTypeIdentifiers

struct CopyTextView: View {
    @State private var text: String = ""
    @State private var buttonText  = "Copy"
    private let pasteboard = UIPasteboard.general
    
    var body: some View {
        GroupBox{
            VStack {
                HStack{
                    Text("Label:")
                    Spacer()
                }
                TextField("Insert text here", text: $text)
                    .textFieldStyle(.roundedBorder)
                    .contextMenu {
                        Button {
                            copyToClipboard()
                        } label: {
                            Text("Copy to clipboard")
                            Image(systemName: "doc.on.doc")
                        }
                    }
                HStack(spacing:10) {
                    Spacer()
                    Button {
                        copyToClipboard()
                    } label: {
                        Label(buttonText, systemImage: "doc.on.doc")
                    }.buttonStyle(.bordered)
                        .foregroundColor(.black)
                    Button {
                        paste()
                    } label: {
                        Label("Paste", systemImage: "doc.on.clipboard")
                    }
                    .buttonStyle(.bordered)  
                    .foregroundColor(.black)
                }.controlSize(.small)
            }
            .padding()
        }.padding()
    }
    
    func paste(){
        if let string = pasteboard.string {
            text = string
        }
    }
    
    func copyToClipboard() {
        pasteboard.string = self.text
        
        self.buttonText = "Copied!"
        // self.text = "" // clear the text after copy
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            self.buttonText = "Copy to clipboard"
        }
    }
}

struct CopyTextView_Previews: PreviewProvider {
    static var previews: some View {
        CopyTextView()
    }
}
Richard Torcato
  • 2,504
  • 25
  • 26