【SwiftUI】クリップボードにコピーする方法!自作ボタンでバルーン表示

この記事からわかること

  • SwiftUIテキストクリップボードコピーする方法
  • コピーしました」のバルーン表示実装方法
  • UIPasteboard.general使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

アプリ開発でなにかと必要になる小技「クリップボードにコピー」。実際の実装方法と使い方、「コピーしました」のバルーン表示の自作方法をまとめていきます。

テキストをクリップボードにコピーさせる方法

SwiftでユーザーのクリップボードへテキストなどをコピーさせるにはUIPasteboardクラスを使用します。

class UIPasteboard : NSObject 

UIPasteboardクラスのgeneralプロパティの中に文字列やURL、画像などの様々な種類のデータを保持することができるので、ここにそれぞれ値を入れ込めばクリップボードにコピーされた状態になります。

// 文字列
UIPasteboard.general.string = "コピーさせたい文字列"

// 画像
UIPasteboard.general.image = UIImage(named: "画像名")

// URL
UIPasteboard.general.url = URL(string: "https://www.amefure.com")

// 色
UIPasteboard.general.color = UIColor.white

あとはこの処理をボタンのアクションの中などで実行すれば押しただけで任意の値をコピーさせることができるようになります。

アプリ内の文字列はコピーできない?

そもそもアプリ内でText表示させている文字列などは触ろうとしても選択/コピーすることができない仕様になっています。

なのでユーザーがコピーできるようにするには今回のようにクリップボードにコードからコピーさせるか下記記事のように選択/コピーが可能になるようにモディファイアを追加しなければいけません。

「コピーしました」バルーン表示の自作

今回はユーザビリティを高めるためにコピーボタンの作成と押されたら「コピーしました」とメッセージ(バルーン表示)が出るようにしていきたいと思います。

【SwiftUI】クリップボードにコピーする方法!自作ボタンでバルーン表示

フレームワークはSwift UIを使用して作成していきます。

ポイント

バルーン表示用のクラスを作成

ますばクラスを作成します。作成するMessageBalloonクラスはプロパティの変化を観測できるようにObservableObjectプロトコルに準拠させておき、プロパティには@Publishedを付与しておきます。

// コピーしました用のメッセージバルーン
class MessageBalloon:ObservableObject{
    
// opacityモディファイアの引数に使用
    @Published  var opacity:Double = 10.0
// 表示/非表示を切り替える用
    @Published  var isPreview:Bool = false
    
    private var timer = Timer()
    
    // Double型にキャスト&opacityモディファイア用の数値に割り算
    func castOpacity() -> Double{
        Double(self.opacity / 10)
    }
    
    // opacityを徐々に減らすことでアニメーションを実装
    func vanishMessage(){
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true){ _ in
            self.opacity = self.opacity - 1.0 // デクリメント
            
            if(self.opacity == 0.0){
                self.isPreview = false  // 非表示
                self.opacity = 10.0     // 初期値リセット
                self.timer.invalidate() // タイマーストップ
            }
        }
    }
    
}

opacityモディファイアでの指定はDouble型で「0〜1」ですが、vanishMessageメソッドで「-0.1」ずつに減らしていくと正確な引き算ができない(Swiftの仕様上)ので「0〜10」の間で「-1」ずつ変化させるようにします。

vanishMessageメソッドではTimerを使用して0.1秒ごとに処理をリピートさせ、opacityの値が0になったタイミングで非表示にしつつ、opacityを初期値に戻しておきます。

ちなみにvanishMessageメソッドのようなクロージャの中で自身のプロパティの値を変更するのは構造体ではできずに以下のようなエラーになるので注意してください。

Escaping closure captures mutating 'self' parameter

コピーボタンの実装

続いてコピーボタンを作っていきます。まずはクラスの変更を観測したいので@ObservedObjectをつけてmessageBalloonのインスタンスを作成します。Button構造体のアクションの中でクリップボードへのコピー処理とバルーン表示を表示させる(isPreviewにtrue)処理を実装します。ボタンが押され表示されている間に再度押されないようにdisabled(messageAlert.isPreview)を渡して無効にしておきます。

Button(action: {
    UIPasteboard.general.string = "コピーしたい文字列"
    messageAlert.isPreview = true
    messageAlert.vanishMessage()

}, label: {
    Image(systemName: "doc.on.doc")
        .foregroundColor(.gray)
        .frame(width: 65)
}).disabled(messageAlert.isPreview)

「コピーしました」バルーンの実装

「コピーしました」部分はTextで実装します。あとはデザインと表示位置を調整してopacityモディファイアにcastOpacityメソッドを渡せばOKです。

クラスのインスタンスを作成する際は変更を検知できるように@ObservedObjectを付与しておくのを忘れないようにしてください。

@ObservedObject  var messageAlert = MessageBalloon()


ZStack {
  if (messageAlert.isPreview){
      Text("コピーしました")
          .font(.system(size: 8))
          .padding(3)
          .background(Color(red: 0.3, green: 0.3 ,blue: 0.3))
          .foregroundColor(.white)
          .opacity(messageAlert.castOpacity())
          .cornerRadius(5)
          .offset(x: -5, y: -20)
  }

  // さっきのボタン

} // ZStack

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index