この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
NJKScrollFullScreenは、スクロール操作に応じてナビゲーションバーなどを表示/非表示することが簡単にできるライブラリです。 スクロールのイベントをフックしてバーの高さを変えるという処理は、元々自前でも記述可能ですが、このライブラリを使用することで、より簡単に気持ちく動作するUIが作成できます。
NJKScrollFullSreenはUIScrollView、UIWebView及び、UITableViewに対応しています。
NJKScrollFullScreenは、MITライセンスで公開されており、CocoaPodで簡単にインストールが可能です。
pod 'NJKScrollFullScreen'
なお、2016年3月現在、最新は、0.2.6です。
ライブラリの導入後は、下記のインポートで利用可能になります。
#import "NJKScrollFullScreen.h"
#import "UIViewController+NJKFullScreenSupport.h"
2 使用方法
(1) ナビゲーションバー/ツールバーの表示・非表示
Cocoapodsで導入後、新しいプロジェクトをSingle View Applicationで作成し、メニューからEditor-Enbed In-Navigation Controllerを選択して、NavigationControllerで始まるようにします。
また、NavigationControllerの設定で、show toolbarにチェックを入れて、上下にバーが表示されるように します。
この状態で、動作確認すると、下図のように上にナビゲーションバーが表示された画面となります。
ちょっと分かりやすいようにナビゲーションバーとツールバーの色を変更しましたが、これは、NavigationControllerの方のNavigation BarとToolbarのBar Tintで変更しています。
続いて、実験的に2つのボタンを置いて、次のようなコードを書いてみます。
動作確認している様子です。
showNavigationBar:やhideNavigationBar:のようなコードで、簡単にバーの表示/非表示ができます。
UIViewController+NJKFullScreenSupport.hの中を確認すると、次のようなメソッドがUIViewControllerに追加されていることが分かります。
#import <UIKit/UIKit.h>
@interface UIViewController (NJKFullScreenSupport)
- (void)showNavigationBar:(BOOL)animated;
- (void)hideNavigationBar:(BOOL)animated;
- (void)moveNavigationBar:(CGFloat)deltaY animated:(BOOL)animated;
- (void)setNavigationBarOriginY:(CGFloat)y animated:(BOOL)animated;
- (void)showToolbar:(BOOL)animated;
- (void)hideToolbar:(BOOL)animated;
- (void)moveToolbar:(CGFloat)deltaY animated:(BOOL)animated;
- (void)setToolbarOriginY:(CGFloat)y animated:(BOOL)animated;
- (void)showTabBar:(BOOL)animated;
- (void)hideTabBar:(BOOL)animated;
- (void)moveTabBar:(CGFloat)deltaY animated:(BOOL)animated;
- (void)setTabBarOriginY:(CGFloat)y animated:(BOOL)animated;
@end
// Compatible method for typo fixed (https://github.com/ninjinkun/NJKScrollFullScreen/pull/23)
@interface UIViewController (NJKFullScreenSupportDeprecated)
- (void)moveNavigtionBar:(CGFloat)deltaY animated:(BOOL)animated __deprecated_msg("Use `moveNavigationBar:animated:`");
@end
今は、Show/Hideで表示・非表示だけを試しましたが、サイズを細かく指定するメソッドもあり、これらを適切なタイミングで呼び出すことで、スクロールに合わせてバーのサイズを変化させることができます。
なお、実装としては、UIViewController+NJKFullScreenSupport.mを見ると、画面サイズを考慮しながら、バーを指定されたサイズに変更するような実装になっていました。
(2) (プロキシー)デリゲート
実験的に置いた、先ほどのボタンは削除し、今度は、画面いっぱいにUIWebViewを置いてみます。
そして、起動時に、Webページを表示するコードを追加します。
※iOS9以降については、ATSを適切に設定してください。
参考:[iOS 9] iOS 9 で追加された App Transport Security の概要
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"https://dev.classmethod.jp/"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[_webView loadRequest:req];
}
動作は、次のとおりです。当然ですが、UIWebViewを操作しても、上下のバーに変化はありません。
ここで、UIWebViewをスクロールした時に、気持ちよく上下のナビゲーションバーやツールバーが消えると画面が広くなって見やすいのですが、そのためには、UIWebViewのスクロールイベントをフックする必要があります。
NJKScrollFullScreenでは、スクロールにあわせて、気持ちよくバーのサイズを変更できるように、必要なスクロール(移動数)を追加してデリゲートとして提供しています。
そして、このために、まずはNJKScrollFullScreenを、対象コントロール(今は、UIWebView)のデリゲートに登録し、さらに、自分自身(今は、ViewController)をNJKScrollFullScreenのデリゲートに登録するという設定が必要です。
普通であれば、UIWebViewのデリゲートに自分自分(ViewController)を設定して処理するスクロールのイベントを、NJKScrollFullScreen経由で受け取るイメージです。
実装としては、次のようになります。 なお、NJKScrollFullScreen.hのインポートと、NJKScrollFullscreenDelegateと追加することも必要です。
#import "NJKScrollFullScreen.h"
#import "UIViewController+NJKFullScreenSupport.h"
@interface ViewController ()<NJKScrollFullscreenDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (nonatomic) NJKScrollFullScreen *scrollProxy;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 省略
// NJKScrollFullScreenの生成
self.scrollProxy = [[NJKScrollFullScreen alloc] initWithForwardTarget:self];
// UIWebViewのスクロールビューのデリゲートにNJKScrollFullScreenをセットする
self.webView.scrollView.delegate = (id)self.scrollProxy;
// NJKScrollFullScreenのデリゲートに自信をセットする
self.scrollProxy.delegate = self;
}
(3) スクロール時の処理
続いて、NJKScrollFullScreenによって提供されるデリゲートメソッドでナビゲーションバー及びツールバーの表示非表示を行います。
- (void)scrollFullScreen:(NJKScrollFullScreen *)proxy scrollViewDidScrollUp:(CGFloat)deltaY
{
[self moveNavigationBar:deltaY animated:YES];
[self moveToolbar:-deltaY animated:YES];
}
- (void)scrollFullScreen:(NJKScrollFullScreen *)proxy scrollViewDidScrollDown:(CGFloat)deltaY
{
[self moveNavigationBar:deltaY animated:YES];
[self moveToolbar:-deltaY animated:YES];
}
- (void)scrollFullScreenScrollViewDidEndDraggingScrollUp:(NJKScrollFullScreen *)proxy
{
[self hideNavigationBar:YES];
[self hideToolbar:YES];
}
- (void)scrollFullScreenScrollViewDidEndDraggingScrollDown:(NJKScrollFullScreen *)proxy
{
[self showNavigationBar:YES];
[self showToolbar:YES];
}
実行している様子は、次の通りです。
3 最後に
簡単なコストで気持ちの良いインターフェースが実装できるNJKScrollFullScreenは、すごいと思います。 今回は、UIWebViewを例にしましたが、最初に書いたとおり、ここは、UIScrollViewやUITableViewに置き換えても同じように使用できます。
なお、下記は、作者のSatoshi Asano氏のGitHub活動について紹介されているスライドです。非常に興味深く読ませて頂きました。
GitHub活動を通して個人のキャリアを積みつつ仕事の成果を出す方法
4 参考資料
COCOAPODS NJKScrollFullScreen
https://github.com/ninjinkun/NJKScrollFullScreen