LoginSignup
1
3

More than 3 years have passed since last update.

はじめに

個人アプリ作成時にフェードイン・アウト機能を実装したので、
コマンドの共有をさせていただきます。

GitHubにコードを載せていますのでぜひご覧ください。
-> https://github.com/onishi-app/FeedInOut

環境

・Apple Swift version 5.3
・XCode version 12.3

完成形

⚠︎4秒おきにフェードイン・アウトが始まります。
nC9RSKQZk5ihDQ0K6HQs1610263334-1610263350.gif

コード

コードの完成形は下記のようになります。

@IBOutlet weak var button: UIButton!で分かる通り、
StoryBoardにオブジェクトを追加しコードと連携しているので
全文コピーしてもコンパイルエラーになります。

ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!
    var timer = Timer()

    override func viewDidLoad() {
        super.viewDidLoad()

        button.layer.cornerRadius = 15

        // timer実装
        timer = Timer.scheduledTimer(withTimeInterval: 4.0, repeats: true, block: { (timer) in
            self.animateView(self.button)
        })

    }

    // フェードイン・アウトメソッド
    func animateView(_ viewAnimate: UIView) {
        UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn) {
            viewAnimate.alpha = 0
        } completion: { (_) in
            UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn) {
                viewAnimate.alpha = 1
            }
        }
    }

    // ボタンが押された時の処理
    @IBAction func buttonAction(_ sender: Any) {
        print("ボタンが押されました。")
    }
}

呼び出し方法

self.animateView(self.button)
フェードイン・アウトのメソッドを呼び出しています。

ViewController.swift

// timer実装
timer = Timer.scheduledTimer(withTimeInterval: 4.0, repeats: true, block: { (timer) in
    self.animateView(self.button)
})

コードの説明

〜フェードイン・アウト〜

フェードイン・アウトを行うためのメソッドanimateView()を定義します。
今回は、UIKitのUIViewクラスに実装されているanimate()メソッドを使います。

ViewController.swift

// フェードイン・アウトメソッド
func animateView(_ viewAnimate: UIView) {
    UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn) {
        viewAnimate.alpha = 0
    } completion: { (_) in
        UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn) {
            viewAnimate.alpha = 1
        }
    }
}

UIViewクラスの中にはいくつかのanimate( )メソッドが記述されているのですが、
今回は下記のメソッドを使用していきたいと思います。

UIKit.UIView

open class func animate(withDuration duration: TimeInterval, delay: TimeInterval, options: UIView.AnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)

第一引数:withDuration duration: TimeInterval
withDurationの値は処理を行う時にかける時間を渡します。

今回は、withDuration: 0.5,のように、0.5秒かけて処理を行うようにしました。

第二引数:delay: TimeInterval
delayには、遅延させる時間を渡します。

delayに1が渡されていたら、メソッドが呼ばれてから1秒後に実行されます。
今回は、delay: 0のように遅延処理は実装しておりません。

第三引数:options: UIView.AnimationOptions = []
optionsには、アニメーション処理を行う際の挙動を指定しています。

optionsには多くの種類があるので一部紹介します。

挙動
repeat アニメーションを無期限に繰り返す
autoreverse 繰り返す場合は、アニメーションを前後に実行します
curveEaseInOut 始めと終わりを緩める動き(デフォルト)
curveEaseIn 始めを緩める動き
curveEaseOut 終わりを緩める動き
curveLinear 等速

この他にも色々あるので気になる方は調べてみてください!

今回は、options: .curveEaseInのように、
はじめの動きを少し緩やかにしています。

第四引数:animations: @escaping () -> Void
animationsには、実行する処理を記述します。

クロージャとして定義されているのでクロージャの形で書きましょう。

今回は、viewAnimate.alpha = 0のように、
引数で渡されてきた値のalpha(透過)を0.5秒かけて0にしています。

alpha = 0 ということは透明にするということです。

第五引数:completion: ((Bool) -> Void)? = nil
completionには、処理が終了した後の処理を記述します。

今回は、UIView.animate( ・・・ )のように、
処理後にまたアニメーション処理を実行しています。

2回目のアニメーション処理は、0.5秒かけてalpha(透過)を1にしています。
つまり、表示されている状態にしている訳です。

2回目のcompletionは、行いたい処理が無いので記述していません。

〜Timerの実装〜

次にTimerの実装についてです。

Foundationに実装されているTimerクラスを使用します。
Timerクラスでは、一定の時間で繰り返し処理を行うことができる機能などが備わっています。

ViewController.swift

var timer = Timer()

// timer実装
timer = Timer.scheduledTimer(withTimeInterval: 4.0, repeats: true, block: { (timer) in
    self.animateView(self.button)
})

Timer.scheduledTimer( ・・・ )が繰り返しの処理になります。

今回は、viewDidLoad( )内に記述しているので、
画面が読み込まれた時点でTimerがスタートされます。

scheduledTimer( )メソッドについて

第一引数:withTimeInterval
こちらは、処理が何秒後に行われるかを記述します。

第二引数:repeats
こちらは、繰り返し処理を行うかどうかを指定します。

trueの場合は繰り返し処理を行い、falseの場合は一度だけ行います。

今回の場合はtrueなので、timerが呼び出されてから4秒後に1回目、
1回目の処理が呼び出されたてから4秒後に2回目・・・という感じで繰り返します。

フェードイン・アウトの時間が合計で1秒あるので、
何もアニメーションが行われない時間が3秒あることになります。

第三引数:block
こちらは、行いたい処理を記述します。
クロージャなので、関数の呼び出しなどにはselfキーワードをつける必要があります。

今回は、self.animateView(self.button)のように
フェードイン・アウトを4秒おきに繰り返し実行しています。

最後に

これでフェードイン・アウト機能の実装完了です。

ただ、現状一つ弱点があります。
というのも、アニメーション中はボタンが反応しないことです。

なので、アニメーション中の1秒間はボタンがタップできず、
フェードインしてから次のフェードアウトまでの3秒間しかタップできません。

もしかしたらアニメーション中に処理を行う方法もあるかもしれませんが、
ぱっと見調べた感じ分からなかったので分かり次第追記したいと思います。

とりあえずは、ボタンをビューに変えてその上に同じサイズの透明のボタンを実装し、
そちらをタップするようにしておこうと思います・・・。

ご存知の方教えて頂けますと幸いです。

楽に実装できるのでぜひ皆さん使って見てください。

以上、最後までご覧いただきありがとうございました。

1
3
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
1
3