4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SwiftUI】パスワード入力欄で間違えたらテキストフィールドをブルブルさせたい(iOS17)

Posted at

はじめに

パスワードの入力欄でよくあるのが、間違ったパスワードを入力すると入力欄がシェイク(ブルブル)して間違っていることを知らせるといったUIです。
これをiOS17から登場したkeyframeAnimatorを使って実装してみたいと思います。

keyframeAnimatorを使用せず、実装したい場合は以下の記事が参考になると思います。

サンプルアプリ

キーボードでreturnを押すと、テキストフィールドがシェイクします。
間違ったものを入力していたという想定です。
Simulator Screen Recording - iPhone 15 - 2024-01-08 at 21.03.45.gif

実装

import SwiftUI

struct KeyframeAnimationValues {
    var offsetX = 0.0
}

struct ContentView: View {
    @State private var text = ""
    @State private var shakeAnimationTrigger = false

    var body: some View {
        VStack {
            TextField("文字を入力してください", text: $text)
                .textFieldStyle(.roundedBorder)
                .keyframeAnimator(
                    initialValue: KeyframeAnimationValues(),
                    trigger: shakeAnimationTrigger
                ) { content, value in
                    content.offset(x: value.offsetX)
                } keyframes: { _ in
                    KeyframeTrack(\.offsetX) {
                        CubicKeyframe(5, duration: 0.2)
                        CubicKeyframe(-5, duration: 0.1)
                        CubicKeyframe(5, duration: 0.1)
                        CubicKeyframe(-5, duration: 0.1)
                        CubicKeyframe(5, duration: 0.1)
                        CubicKeyframe(0, duration: 0.2)
                    }
                }
                .onSubmit {
                    shakeAnimationTrigger.toggle()
                }
        }
        .padding(20)
    }
}

解説

アニメーションで必要な値を構造体で定義します。
今回はoffsetのxをいじりたいのでoffsetXを定義します。

struct KeyframeAnimationValues {
    var offsetX = 0.0
}

アニメーションのトリガーを定義します。

@State private var shakeAnimationTrigger = false

initialValueには先ほど作成した構造体を初期化して渡します。
triggerに先ほど定義したトリガーを渡します。
keyframesで継続時間と値をセットで渡します。
keyframesで設定した値がvalueとして流れてくるので、content.offset(x:)value.offsetXを設定します。

.keyframeAnimator(
    initialValue: KeyframeAnimationValues(),
    trigger: shakeAnimationTrigger
) { content, value in
    content.offset(x: value.offsetX)
} keyframes: { _ in
    KeyframeTrack(\.offsetX) {
        CubicKeyframe(5, duration: 0.2)
        CubicKeyframe(-5, duration: 0.1)
        CubicKeyframe(5, duration: 0.1)
        CubicKeyframe(-5, duration: 0.1)
        CubicKeyframe(5, duration: 0.1)
        CubicKeyframe(0, duration: 0.2)
    }
}

今回はonSubmitで毎回シェイクされるようにshakeAnimationTriggertoggle()します。
shakeAnimationTrigger = trueのようにすると値がfalseに戻らないので正常に動作しません。

.onSubmit {
    shakeAnimationTrigger.toggle()
}

おわり

KeyframeAnimationについて以前書いた記事はこちらです。

KeyframeAnimationがあると色んなアニメーションが作れて楽しいです

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?