【Swift】カスタムのToastメッセージをUIViewControllerから呼び出せるようにする

アプリ内でユーザーに状態の変化を通知する際にUIAlertViewなどは少し仰々し過ぎたので、Androidのような簡単なToastメッセージをiOSでも出せないかと思い色々と調べました。

この記事では以下の2パターンのToastメッセージの出し方を書いていきます。

  1. 文字のみの右上に固定されたToastメッセージ
  2. LottieAnimationと組み合わせた動きのあるToastメッセージ

1.文字のみのToastメッセージ

前提として、UIViewControllerから呼び出すことを想定するので、UIViewControllerのextensionメソッドとして作っていきます。

 

コード数も少ないのでいきなり完成したものから出しますが、Toastメッセージを呼び出すメソッドは下記になります。

 

 

それでは読み砕いていきましょう。

 

手順をまとめると、以下の4つの流れになります。

  1. ToastメッセージのコンテナとなるUIViewを作成する
  2. メッセージを挿入するUILabelを作成する
  3. ラベルの長さなどから最初に作ったコンテナUIViewのFrameを再定義する
  4. 3秒かけてToastメッセージを削除する

 

順をおって説明していきます。

1-1.ToastメッセージのコンテナとなるUIViewを作成する

 

↑の部分です 。

ToastMessageShadowはUIViewを継承してるカスタムクラスになります。影を入れないと境界線が分かりづらかったので作りました。(コードは追記します。)

 

toastViewのFrameは後ほど再定義するので、高さ以外は適当に入れています。高さは35ptにしていますが、ここは適宜お好みで問題ないです。

 

そして、一応通知メッセージをタイプ分け出来るようにしています。タイプがそれぞれ「alert」の場合は背景が赤く、「success」の場合は背景が緑に、そして「notice」の場合は青くなります。

 

ToastMessageShadowのコードは以下になります。

 

1-2.メッセージを挿入するUILabelを作成する

 

↑の部分です。

メッセージを挿入するUILabelを作成します。

このUILabelは先ほど作ったtoastViewの中に挿入するので、Frameの内容はtoastViewと相対的になっています。

 

toastViewに少しpaddingを入れたいので、UILabelのx座標は左から10ptほど離れるようにし、同じく右からも10ptほど離れるようにしたいので、横幅をtoastViewの横幅 – 10ptにしています。

 

さらに、font sizeを17ptにするのでUILabelの高さも17ptにします。toastViewの高さは35ptなので、35 – 17で余りが18ptあります。toastViewの中心にUILabelを据えたいのでy座標を18の半分の9ptにします。

 

これでUILabelのFrameは完成しました。あとはメッセージをUILabelに挿入して、色やalignmentを設定していきます。

 

1-3.ラベルの長さなどから最初に作ったコンテナUIViewのFrameを再定義する

 

↑の部分です。

まず、メッセージの幅にラベルの幅をsizeToFitメソッドで合わせます。そして先ほど適当に作ったtoastViewのFrameを再定義していきます。

 

この記事では右上に固定したいので、まず右上のx座標を計算していきます。

画面の横幅からラベルの横幅を引き、ラベルのx paddingに20ptほどあるのと画面の右端から10pt離したいので、更に30pt引いていきます。

 

y座標はステータスバーの44ptとナビゲーションバーの97ptとpadding分の10ptで合計151ptほど離しています。

 

横幅は先ほどsizeToFitしたUILabelの横幅にx padding分の20ptを足します。

 

高さは変わらず35ptです。

 

そして、autoresizingMaskで定義した座標から動かないようにし、完成です。

あとはtoastViewにUILabelをaddSubviewしてからUIViewControllerのViewにaddSubviewします。

 

1-4.3秒かけてToastメッセージを削除する

 

↑の部分です。

Toastメッセージなので、自動的に消えるようにします。

UIViewには便利なanimateメソッドがあるので、それを使っていきます。

 

ちゃんとユーザーがメッセージを認識できるように、2秒ほどdelay(遅延)をかけて、その後に1秒間でtoastViewの透明度を0にし、少し上に浮くようにanimationが適用されます。animationが終わったら、toastViewを親のViewから削除します。

 

以上で、文字のみのToastメッセージ完了です。

使い方はUIViewControllerから以下のように呼び出せます。

 

2.LottieAnimationと組み合わせた動きのあるToastメッセージ

この例では、先ほど紹介した文字のみのToastメッセージの応用でLottie AnimationをtoastViewに追加していきます。

 

LottieとはAirbnbが作ったアニメーションのRendererで、iOS・Android・Webなどで簡単にアニメーションを再生出来るライブラリを提供しています。

この記事では詳しいことは割愛しますが、気になる方は下記の記事を参考にしてください。

 

それではいきなり完成したものから出します。Lottie Animation付きのToastメッセージを呼び出すメソッドは下記になります。

 

それでは読み砕いていきましょう。

 

手順をまとめると、以下の4つの流れになります。

  1. ToastメッセージのコンテナとなるUIViewを作成する
  2. アニメーションのコンテナとなるLottieAnimationViewを作成する
  3. メッセージを挿入するUILabelを作成する
  4. 3秒かけてToastメッセージを削除する

 

順をおって説明していきます。

 

2-1.ToastメッセージのコンテナとなるUIViewを作成する

 

↑の部分です。

CornerShadowViewもまた、UIViewクラスを継承しているカスタムクラスになります。こちらのコードも後ほど追記します。

 

今回はアニメーションが追加されていることから、Toastメッセージのコンテナはやや大きめに、画面の中心から少し上あたりに配置しようと思います。

 

画面の横端からそれぞれ25pt離れるようにしたいので、x座標を25pt、横幅を画面の横幅引く25ptにします。

 

y座標は画面の中心y座標から150pt程上に置きます。

 

最後にToastメッセージの高さは画面の高さを三分割にした高さにします。

 

CornerShadowViewのコードは以下になります。

 

2-2.アニメーションのコンテナとなるLottieAnimationViewを作成する

 

↑の部分です。

アニメーション用のViewはLottieライブラリのAnimationViewを使って予めダウンロードしてあるjson fileを呼び出しています。

 

Lottieのアニメーションファイルは以下のサイトからダウンロード出来ます。

CCライセンスも数多く投稿されていますし、もちろんMarketplaceから購入することも出来ます。

 

話を戻しまして、lottieAnimationViewはtoastViewの上半分あたりに置き、左右のpaddingは25ptほどにします。

 

まず、lottieAnimationViewの寸法を画面の横幅の1/4の長さに定義します。

ですので、lottieAnimationViewのx座標は画面の中心x座標からlottieAnimationView自身の辺の長さ(画面横幅の1/4)を更に半分にして、padding分の25ptを引いた値になります。

 

y座標は適当に25pt上に開けています。

 

長さと高さは先ほど定義した通りの、画面横幅の1/4の長さです。

 

あとはaspectFitさせて、toastViewにaddSubviewします。

 

2-3.メッセージを挿入するUILabelを作成する

 

↑の部分です。

次に、toastViewの下半分のメッセージ部分を作っていきます。

 

UILabelのx座標はtoastViewの右端から25pt程離します。

 

y座標はlottieAnimationView分の高さと25pt程更に離してます。

 

横幅はtoastViewの横幅にpadding分の50ptを引いています。

 

高さはきっかり計算するのがめんどくさかったので、適当にlottieAnimationViewの高さと同じにしちゃっています。多分少しだけ無駄な空間が出来るかもしれません。

 

一応、ラベルが2段になっても問題ないようにnumberOfLinesを0にし、行間を1.7ぐらいに設定しています。

 

その他のラベル設定が完了したら、toastViewにaddSubviewしてからtoastViewをUIViewcontrollerのViewにaddSubviewします。

 

そしてこのままですとアニメーションが再生されないので、playメソッドからアニメーションを再生します。

 

4. 3秒かけてToastメッセージを削除する

 

↑の部分です。

ここは1-4.で紹介した内容と大体同じなので、割愛します。

このメソッドも先ほどと同様、UIViewControllerから以下のように呼び出せます。

 

以上、カスタムのToastメッセージをUIViewControllerから呼び出す方法でした。

最終的なコードは以下になります。

 

 

クレジット

Lottie Animation: Favourite app icon

by Michael Harvey

 

参考URL