【SwiftUI】State 付きボタンのアニメーション記述

公式チュートリアルを見ながら。


Animating views and transitions — SwiftUI Tutorials | Apple Developer Documentation

思いついたものを書きなぐり試す。



 

🤔 まとめ

- animation(), withAnimation() 記述がなくても effect にはデフォルトでアニメーションがつく。
- animation() で 個別に effect のアニメーションを変更や削除ができる。
- withAnimation() でアニメーションの変更や削除ができる。



【SwiftUI】Apple 公式サンプルでは Animation と Transition をどのように組み合わせているのか

画面上にメッセージを表示する View。


import SwiftUI

struct Message: View {
  var text: String

  var body: some View {
    HStack(spacing: 0) {
      Image(systemName: "heart.fill")
        .foregroundStyle(.red)
        .font(.title)
        .padding()
      Text(text)
        .padding(.trailing, 24)
    }
    .clipShape(.capsule)
    .background(
      .regularMaterial.shadow(.drop(radius: 16)),
      in: .capsule
    )
  }
}

#Preview {
  Message(text: "Hello, world!")
}

どのように、アニメーションやトランジションをつけて、生き生きとした画面にしているか。

Apple 公式サンプルを参考に書いてみます。

 

🧑🏻‍💻 Preview 用 View の準備

挙動を何度も確かめるために、

Preview 専用の View を作っておきます。


private struct RefreshPreview: View {
  var text: String

  @State private var id = false

  var body: some View {
    Message(text: text)
      .id(id)

    Button("Refresh") {
      id.toggle()
    }
    .buttonStyle(.borderedProminent)
  }
}

👉 【SwiftUI】View の 強制再描画 hatena-bookmark

ボタンを押すと強制的に画面再描画がされて、

表示開始からの動きを確認できるようになります。

 

🧑🏻‍💻 まずは アニメーション・トランジションなしでつくる


import SwiftUI

struct Message: View {
  var text: String

  @State private var showIcon = false
  @State private var showText = false

  var body: some View {
    HStack(spacing: 0) {
      if showIcon {
        Image(systemName: "heart.fill")
          .foregroundStyle(.red)
          .font(.title)
          .padding()
      }
      if showText {
        Text(text)
          .padding(.trailing, 24)
      }
    }
    .clipShape(.capsule)
    .background(
      .regularMaterial.shadow(.drop(radius: 16)),
      in: .capsule
    )
    .frame(height: 50)
    .onAppear {
      Task {
        showIcon = true
        try await Task.sleep(for: .seconds(1))
        showText = true
        try await Task.sleep(for: .seconds(1))
        showText = false
        try await Task.sleep(for: .seconds(1))
        showIcon = false
      }
    }
  }
}

private struct RefreshPreview: View {
  var text: String

  @State private var id = false

  var body: some View {
    Message(text: text)
      .id(id)

    Button("Refresh") {
      id.toggle()
    }
    .buttonStyle(.borderedProminent)
  }
}

#Preview {
  RefreshPreview(text: "Hello, world !!!")
    .padding()
    .frame(maxWidth: .infinity)
}

アイコン画像とテキスト部分をそれぞれの @State で


アイコン表示 

  ↓

テキスト表示

  ↓

テキスト非表示

  ↓

アイコン非表示

と Task の中で1秒ごとに変化させています。

しかし、アニメーションやトランジションがないので、

スムーズに View が変化しません。

 

🧑🏻‍💻 アニメーション・トランジションをつける



 

🧑🏻‍💻 まとめ

やっぱ、全然違いますね。

👉 sample-backyard-birds/Multiplatform/Birds/BirdFoodHappinessIndicator.swift at main · apple/sample-backyard-birds hatena-bookmark

 

🧑🏻‍💻 追記: 上記のトランジションっている ?

withAnimation() 記述は必要だとして、

transition() 記述は不要なのではないか。

できるだけシンプルにテンプレート化しておきたいので、

0.25 倍の速度で確認してみます。

上がトランジションなし、

下がトランジションあり。

トランジションはあったほうがいいですね。

やっぱり、Apple 公式サンプルコードは偉大。



【Mac】ユニバーサルコントロール / ディスプレイ が頻繁に途切れる ときの対処法

一つのキーボードで複数の Mac を操作し、ディスプレイも行き来できる「ユニバーサルコントロール」。

便利なのだが、頻繁に途切れると、逆にイラッとする。

👉 ユニバーサルコントロールが時々切れる - Apple コミュニティ hatena-bookmark
👉 ユニバーサルコントロールがすぐ切れ、再設定しても、なかなか安定しない - Apple コミュニティ hatena-bookmark
👉 「キーボードとマウスをリンク」が頻繁に切れる- Apple コミュニティ hatena-bookmark
👉 ユニバーサルコントロールでマウスを他のデバイスを行き来できますが、戻ってこれなくなる現象がでていて困っています - Apple コミュニティ hatena-bookmark
👉 iMac のユニバーサルコントロールを接続する候補として MacBook Pro が表示されず、接続できない状況が頻繁に生じます - Apple コミュニティ hatena-bookmark

Apple 公式フォーラムにも多数のコメントが上がってます。

 

🧑🏻‍💻 途切れたときの再接続方法

「設定」から「ディスプレイ」を開く と再接続されます。

開いたら何もせずに、接続を確認できたらそのまま閉じるだけです。

 

🧑🏻‍💻 ショートカットに入れておくと便利

結構不安定で、頻繁に切断されるので。

いちいち、切れるたびに「設定」-「ディスプレイ」と開くのもだるい。

コマンドラインなら、「『設定』-『ディスプレイ』を開く」の動作は、


open "x-apple.systempreferences:com.apple.Displays-Settings.extension"

なので、ショートカットに入れておくと簡単に接続できて便利です。

ショートカットのコンポーネントとしては、

Scripting の

「Run AppleScript」か「Run Shell Script」か

Web の

「Open URLs」

でいけそうです。

などの詳細は以下より。

👉 【便利】Mac パスワードマネージャー を メニューバーのショートカット や コマンドラインから開く方法 hatena-bookmark

 

🧑🏻‍💻 まとめ

以下のようなショートカットにしておきます。

開いて、3秒待ってから、閉じます。