ワシはワシが育てる

週刊少年ジャンプと任天堂のゲームが三度のメシより好きです。

iOSでページバック時にアニメーションがカクつくときの対処法

View構造が複雑なページでBackボタンや「popViewControllerAnimated」を呼び出した時にアニメーションがカクつく事があります。

対処法は簡単でviewWillDisappearに以下の二行を追加するだけです。

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    self.view.layer.shouldRasterize = YES;
    self.view.layer.rasterizationScale = [UIScreen mainScreen].scale;
}

好みが分かれるようで導入してないプロジェクトもあるとは思いますが、私はBaseUIViewControllerを作っておいてユーザーが触れる画面はそれを継承するようにしています。

普通のCSSボタンとinputボタンのサイズを揃える方法

input type="submit" value="hoge"のようなinputボタンと普通にCSSでスタイリングしたボタンのサイズが合わなかった時のメモ。

inputにはデフォルトで値が設定されているので、それらを解除します。
解除が必要なプロパティは以下のものがあります。

  • border
  • margin
  • padding
  • box-sizing
  • line-height

個人的にline-heightを見落としていてハマってしまいました。
chromeのdeveloper consoleを見るとデフォルトのプロパティが確認できるので、合わない時は地道にデフォルト値を追っていくと良いでしょう。

iOSでアプリの許可情報をリセットする方法

連絡先などの許可状態に合わせて画面を切り替えたいような場合、一度許可・不許可を設定してしまうと、「まだ設定されていない状態」に戻す方法がないかと調べたのでメモ。

アプリをアンインストールするだけだと、設定されていない状態に戻すことが出来ません。
そこで端末の「設定」→「一般」→「リセット」→「位置情報とプライバシーをリセット」と行くことで全ての許可情報をリセットすることができます。

ただPCの信頼情報や他のアプリも同時にリセットされてしまうので注意。

※日常的に使っている実機でやると死ぬほど面倒くさいので、テスト端末かシミュレータでやりましょう!

EventBusを使ってAndroidでNSNotification的なものを実装する

iOS開発を2ヶ月ほど行った後、再びAndroidに戻ったのですが、NSNotification(クラスをまたいだ通知)をAndroidで実装するのがデフォルトのままだと面倒だなーと感じていました。
そこでライブラリを探したところ、EventBusが非常に便利だったので紹介します。

Githubページにあるように、行うことは以下の3つだけです。

  • イベントを媒介するクラスを作成する(継承は必要ではなく単なるJavaのクラス)
  • イベントを受信するクラスでEventBusのインスタンスを登録する
  • イベントを送信するクラスでEventBusのインスタンスを通じて送信する

イベントを媒介するクラス

これは通常のJavaのクラスで何も継承する必要はありません。 イベントを受信する際、引数でこのクラスのインスタンスを取り出すことになります。

単なるクラスである以上、実装方法は種々あると思いますが、一例として送信したいデータをそのままクラス変数に格納してしまうこともできます。

class EventClass {
    private EventClass mEventClass;

    // 例えばフォロー数の変更を検知する
    public int followCount;
    public boolean followChanged;

    public static EventClass getInstance() {
        if (mEventClass == null) {
            mEvnetClass = new EventClass();
        }

        return mEventClass;
    }
}

イベントを受信するクラス

イベントを受信するクラスでは、EventBusインスタンスの登録と、受信した際に呼ばれるメソッドを定義します。

// 登録
EventBus.getDefault().register(this); 

// イベント受信時に呼ばれる
// IDEでは未使用とみなされますが気にしないでください
public void onEvent(EventClass eventClass) {
    if (eventClass.followChanged) {
        /* do something */
    }
};

イベントを送信するクラス

イベントを送信するクラスでは、任意のタイミングでEventBusインスタンスのpostメソッドを呼び出します。その際、引数として対象のイベントクラスのインスタンスをセットします。

EventClass eventClass = EventClass.getInstance();
eventClass.followCount = 50;
eventClass.followChanged = true;
EventBus.getDefault().post(eventClass);

例に書いたとおりに実装すると、EventClassのクラス変数を通じてフォロー数の変更を通知することが出来ます。

GridViewにfooterViewをつけてローディングを表示する

Androidで無限スクロールする場合、追加読み込み発生時にProgressBarをfooterViewに付与するのが通常ですが、通常のGridViewにはfooterViewをつけることができません。

そこでfooterViewをつけられるカスタムのGridViewがオープンソースとしていくつか出ていますが、個人的にはandroid-GridViewWithHeaderAndFooterがオススメです。

(他のライブラリを試したところLolipop環境でバグが発生してしまったので、こちらのライブラリを使用しています。)

gradleを使用している場合はdependenciesに以下を追加します。

compile 'in.srain.cube:grid-view-with-header-footer:1.0.9'

インストール後はGridViewの代わりにin.srain.cube.views.GridViewWithHeaderAndFooterをlayoutに付与すれば使用できます。

例えばfooterViewを追加する際は以下のようにします。

GridViewWithHeaderAndFooter gridView;

View loadingView = LayoutInflater.from(context).inflate(R.layout.footer_view, null);
gridView.addFooterView(loadingView);
gridView.setAdapter(adapter);

setAdapterなど通常のGridViewが持つ機能も当然あるので、あまりトラブルなく使用できるかと思います。

AndroidでViewの移動アニメーションを行う

AndroidのAnimationにはいくつかの種類があり、Viewの座標を移動するためのものとしてTranslateAnimationが存在します。

しかしこのアニメーションにはバグがあるようで、アニメーションの終了後に初期状態の座標に戻されてしまいます。
そのため個人的には移動アニメーションにはObjectAnimatorをオススメします。

使用例として以下のように設定します。

ObjectAnimator animator = ObjectAnimator.ofFloat(`対象のView`, "translationY", `初期の座標`, `終了時の座標`);
animator.setDuration(`時間をミリ秒で指定`);
animator.start();

この場合はY座標の移動としてtranslationYを指定しましたが、X座標の場合はtranslationXを指定します。

Railsで静的ファイルをS3に置くならasset_syncがオススメ

RailsのアプリケーションでprecompileしたassetファイルをAmazon S3から読み込みたい、という時にはasset_syncというgemがオススメです。

asset_syncの設定後、precompileをすると対象のS3バケットにCSSや画像などの静的ファイルが自動でアップロードされ、特定の環境時(通常はproduction)でのみassetファイルをS3から読み込んでくれます。

インストールには関連ライブラリも併記して、Gemfileに以下のように追加します。(手順は公式サイトに書かれているものを要約したものです)

gem "fog", "~>1.20", require: "fog/aws/storage"
gem "asset_sync"

インストールしたら設定ファイルを作成します。
まずconfig/initializers/asset_sync.rbに以下の内容を追加します。

AssetSync.configure do |config|
  config.fog_provider = 'AWS'
  config.fog_directory = (バケット名)
  config.aws_access_key_id = (AWSのアクセスキー)
  config.aws_secret_access_key = (AWSのシークレットキー)
  config.manifest = true
  config.fog_region = (リージョン, 東京なら`ap-northeast-1`)
end

次にconfig/environments/production.rbに以下を追加します。(production以外の環境で導入したい場合はenvironments以下の対象のファイルに同様に記述します)

config.action_controller.asset_host = (S3のルートURL)

設定はこれで終了です。
precompileしてRailsをproductionモードで起動すると、アセットファイルの取得先がconfig.action_controller.asset_hostで指定したものに変更されているかと思います。

このようにproduction環境だけS3ファイルにして、developmentやstaging環境ではローカルのassetファイルを読み込みたい、といった状況に簡単に対応できて非常に助かります。