投稿日:

【iOS】ユニークなWebページ読み込みインジケータを作ってみた

Coard for iPad UIActivityIndicator デザイン オリジナル 自作 swift おすすめ




iPadアプリで更新情報ページへアクセスするための内臓ブラウザを使っているんですが、iOSのUIActivityIndicator(下の画像)を使うことに嫌気がさしてしまいました。


Coard for iPad UIActivityIndicator デザイン オリジナル 自作 swift おすすめ


というのも、iPhone4の頃からずっと見てきてさすがに飽きましたし、
読み込み状況と関係なく回り続けているだけなので、読み込みがちゃんと進んでいるのか不安になることがあるんです。

かといって定番のHUDは組み込むのが面倒で面白みもなかったので、思いつく限りで何か簡単なものを自作することにしました。











動画


WindowsのModern UIプログレスに似ています。

Web loading indicator design. -Coard #ios #ui #animation

CoardWare UIさん(@coardwareinterface)が投稿した動画 –




特徴について


Coard for iPad UIActivityIndicator デザイン オリジナル 自作 swift おすすめ


主な特徴は以下。

・左上の大きな●は従来通り、読み込み処理実行中を表現
・中央の上から落ちてくるものがいわゆる「プログレスバー」的なもの
・上から下へ落ちるアニメーションによってデータ受信そのものを表現
・プログレスの到達点なるものはないが、同じページは落ちる数に大差ないので、「あとどれくらいで完了か」がなんとなくわかってくる
・実装が難しくない



左上のインジケータはもともと使うつもりではなかったんですが、プログレスが意外とすぐに落ちてこないため併用することにしました。

当初はインジケータを中央に表示し、プログレスが来たら隠すようにしていましたが、通信状況によってプログレスの間隔に間が空くので左上で常に表示させておくことに。

実装はこれからご紹介しますが、実装レベルの割りになかなかイケてるものができたと個人的に満足しています。



実装


まずはドロップアニメーションから。
webViewDidFinishLoad()が呼ばれるたびにドロップアニメーションを実行しているだけです。


UIWebViewデリゲートメソッドのwebViewDidFinishLoad(webView: UIWebView)内で以下を実装すればokです。

if webView.loading { // trueであれば読み込み中
            
            let dropProgress = UILabel()
            dropProgress.frame = CGRectMake(0, -50, 30, 30)
            dropProgress.setCenterX(webView.width() / 2)
            dropProgress.text = "●"
            dropProgress.textAlignment = .Center
            dropProgress.font = .systemFontOfSize(25)
            dropProgress.textColor = UIColor.blueColor()
            dropProgress.backgroundColor = UIColor.clearColor()
            webView.addSubview(dropProgress)
            
            UIView.animateWithDuration(0.6, delay: 0, options: .CurveEaseOut, animations: {
                    dropProgress.frame.origin.y = webView.height()
                }, completion: { value in
                    dropProgress.removeFromSuperview()
            })
            
            return
        }
        
		//// 読み込み完了でここを通るのでアルファインジケータの後始末をする
        _stopIndicator = true




●の描画はしたくなかったのでUILabelにこれ→●をセット。
そしてアニメーションでwebViewのheightをdropIndicator.frame.origin.yへセットすればちゃんと隠れます。
このときEaseOutオプションにしておくと減速効果が素敵に映ります。



続いてアルファアニメーションのループメソッド。

var _stopIndicator = false

func alphaAnimation(alpha: CGFloat, setAlpha: (a: CGFloat) -> Void) {
    UIView.animateWithDuration(0.8, delay: 0, options: .CurveEaseInOut, animations: {
            setAlpha(a: alpha)
            }, completion: { value in 
                
                if _stopIndicator { // trueならalphaゼロにしてループ終了
                    UIView.animateWithDuration(0.8, delay: 0, options: .CurveEaseInOut, animations: {
                        setAlpha(a: 0)
                        }, completion: { value in })
                    return
                }
                
                let nextAlpha: CGFloat = alpha == 1.0 ? 0.0 : 1.0 //現在のalphaから判定
                alphaAnimation(nextAlpha, setAlpha: { (a: CGFloat) in 
                    setAlpha(a: a)
                })
        })
}



クロージャ使ってますし、ループするので循環参照に注意が必要です。(そしてもっとマシなアルゴリズムあるかも)

EaseInOutオプションとduration0.8の組み合わせにより、ホワーンホワーンというホタルの光(またはWindowsのCortana)のようなアニメーションを実現できます。

このメソッドをインジケータ作成後、alphaゼロを引数に呼び出します。



let indicator = UILabel()
    indicator.frame = CGRectMake(10, 10, 60, 60)
    indicator.text = "●"
    indicator.textColor = UIColor.blueColor()
    indicator.textAlignment = .Center
    indicator.font = .systemFontOfSize(90)
    indicator.backgroundColor = clearColor
    webview.addSubview(indicator)
    
    alphaAnimation(0.0, setAlpha: { (a: CGFloat) in 
        indicator.alpha = a
    })



以上、自作インジケータでした。


Sponsored Link





Comment