relux iOSアプリにNavigationDrawerを実装
relux iOSアプリにNavigationDrawerを実装しました。
いくつかライブラリも検討したのですが、条件に会うものがなくスクラッチ開発しました。
その時に気をつけたことや工夫したことを紹介したいと思います。
NavigationDrawerとは?
画像のように左側からスライドして表示されるメニューがNavigationDrawerです。
詳しくはGoogle design guidelinesを参照
Navigation drawer - Patterns - Google design guidelines
求める要件
レイアウト
レイアウトはあとから変更になる可能性が高いので
Storyboard(AutoLayout)を使用しています。
左側のメニュー部分はUITableView、右側の透過している部分はUIViewです。
透過している部分はTouch時にドロワーメニューを閉じるようになっています。
ユーザ情報セル
背景画像は季節毎に変更できるようにサーバから取得するようにしています。
頻繁に変わるものではないですが変更した際にすぐに反映させたかったので
画像のキャッシュ期間は1日としています。
ここでは画像の上に文字をのせるので視認性をあげるためにグラデーションをかけています。
// グラデーションをかける処理 UITableViewCellなどでは複数回呼ばれないように注意 CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height); gradient.colors = @[ (id)[UIColor clearColor].CGColor, (id)[UIColor blackColor].CGColor ]; [view.layer addSublayer:gradient];
アイコン画像は丸くトリミングし、名前と会員IDをアイコンの横にならべて表示しています。
// 画像を丸くトリミング view.layer.cornerRadius = view.frame.size.width * 0.5f; view.clipsToBounds = YES;
名前のフォントサイズはかなり大きめに設定していますが
スペースを十分に設けているので実機でみると違和感はありませんでした。
メニューセル
メニューのアイコンはGoogleのMaterial iconsを使用しています。
Androidアプリでよく使われるアイコンですがiOSで使用しても違和感はありません。
ただし、システムアイコンとならべるとボーダーが太いので気をつける必要があります。
design.google.com
メニューセルではRippleEffect(波紋アニメーション)はあえてつけませんでした。
技術的にはつけることは可能なのですが、
iOSらしくない動きであること
古い端末を考慮するとスペック的に厳しいことから実装しませんでした。
レイアウト順序
メニュー部分のレイアウト順序は追加・変更になることがわかっていたので
担当エンジニア以外でも簡単に変更できるように定数で持っています。
#define NAVIGATION_DRAWER_USER_INFO_ROW 0 #define NAVIGATION_DRAWER_USER_BOOKING_CONFIRMATION_ROW 1 #define NAVIGATION_DRAWER_USER_FAVORITE_ROW 2 #define NAVIGATION_DRAWER_USER_HISTORY_ROW 3
スピード優先で実装しているとハードコーディングしてしまいがちですが
あとで困るのは自分なので こういう部分は意識して定数にするようにしています。
CustomTransitionの実装
今回使用したのは以下になります。
UIViewControllerAnimatedTransition
- transitionDuration
- animateTransition
UIPanGestureRecognizer
UIPercentDrivenInteractiveTransition
実装方法についてはAppleドキュメントに記載されているので
紹介はしませんが工夫した点があるので紹介します。
developer.apple.com
指にあわせて動かす工夫
実装時に一番苦労した部分でもあります。
右側の透過部分を含めて1画面としているので
そのまま実装してしまうと指についてこないように見えてしまいます。
そこで画面の幅から計算して擬似的に指についてくるように実装しました。
offset分だけずらしてcontrollerの横幅で除算することで割合を算出しています。
case UIGestureRecognizerStateChanged: { CGFloat width = controller.view.bounds.size.width; CGFloat fraction = MAX([gesture translationInView:controller.view].x + offset, 0) / width; if (fraction > 1.0f) { fraction = 1.0f; } _shouldCompleteTransition = fraction > INTERACTION_THRESHOLD; [self updateInteractiveTransition:fraction]; }
やってみて感じたこと
今までCustomTransitionはあまり使っていなかったのですが、実装してみるとそんなに難しくありませんでした。
CustomTransitionを実装るすことによって他のアプリとは違った動きになるので、他の画面でもどんどん取り入れていきたいと考えています。
良かったら実際のアプリを触ってみてください!
いつものreluxを、アプリでも。 | relux