UIWebViewの上下スクロールでツールバー表示非表示 | 人生、全て中途半端

人生、全て中途半端

iPhoneアプリ開発初心者が調べたことの備忘録。
あと、趣味のマラソンあれこれ。

UIWebViewでツールバーを表示したい(というか必須)が画面が狭くなってしまうので、iOS7のSafariで実装されてるツールバーの非表示を実現したい。 参考にさせていただいたのはこちら
ただ、初心者の自分にはサンプルコードの記述が足りなく、大変苦労したのでプラスαで記載(転載?)。
仕様についてはそのままコピペ
  • 画面の下を見ようとする動作でツールバー消す
    • 上に向けてフリック
    • スクロール後のy軸オフセット値がスクロール前より増える
    • =>スクロールビューのdelegateでオフセット値を計算
    • => scrollViewWillBeginDragging:でスクロールし始めを取得
    • => scrollViewDidScroll:でスクロール後に増えてたら消す
  • 画面の上に戻ろうとする動作でツールバーを表示
    • 下に向けてフリック
    • スクロール後のy軸オフセット値がスクロール前より減る
    • =>スクロールビューのdelegateでオフセット値を計算
    • => scrollViewWillBeginDragging:でスクロールし始めを取得
    • => scrollViewDidScroll:でスクロール後に増えてたら表示
  • ツールバーはアニメーションで消す
    • すでにアニメーションが行われていれば割り込まない
    • =>フラグもしくは列挙体でステータスを制御

ViewController.h
  • スクロールのステータスを表すenumを用意しておく
  • スクロールビューdelegateの設定
  • スクロールステータスのプロパティを用意
  • スクロールしはじめのオフセット値を保持するプロパティを用意
typedef enum {
    QVToolBarScrollStatusInit = 0,
    QVToolBarScrollStatusAnimation ,
}QVToolBarScrollStatus;
@interface ViewController : UIViewController <uiscrollviewdelegate> {
    UIWebView *wv;
    UIToolbar *toolBar;
}
@property (nonatomic, retain) IBOutlet UIWebView *wv;
@property (nonatomic, retain) IBOutlet UIToolbar *toolBar;
@property (nonatomic) BOOL toolBarScrollStatus;
@property (nonatomic) CGFloat beginScrollOffsetY;
@end
注)このすぐ上の20行目は無視して下さい。勝手にSyntaxHighlighterが追加してる模様。
ViewController.m
  • viewDidLoadにスクロールdelegete記述
  • スクロールし始めた際にオフセット値を設定
  • スクロールし続ける度にオフセット値を判定して表示非表示を実行
@implementation ViewController
@synthesize wv;
@synthesize toolBar;


- (void)viewDidLoad {
    [super viewDidLoad];
    //スクロールdelegate用
    self.wv.scrollView.delegate = self;
}
//スクロールビューをドラッグし始めた際に一度実行される
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    self.beginScrollOffsetY = [scrollView contentOffset].y;
}
//スクロールビューがスクロールされるたびに実行され続ける
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (QVToolBarScrollStatusAnimation == self.toolBarScrollStatus) {
        return;
    }
    if (self.beginScrollOffsetY < [scrollView contentOffset].y
        && !self.toolBar.hidden) {
        //スクロール前のオフセットよりスクロール後が多い=下を見ようとした =>スクロールバーを隠す
        [UIView animateWithDuration:0.4 animations:^{
            self.toolBarScrollStatus = QVToolBarScrollStatusAnimation;
            CGRect rect = self.toolBar.frame;
            self.toolBar.frame = CGRectMake(rect.origin.x,
                                            rect.origin.y + rect.size.height,
                                            rect.size.width,
                                            rect.size.height);
        } completion:^(BOOL finished) {
            self.toolBar.hidden = YES;
            self.toolBarScrollStatus = QVToolBarScrollStatusInit;
        }];
    } else if ([scrollView contentOffset].y < self.beginScrollOffsetY
               && self.toolBar.hidden
               && 0.0 != self.beginScrollOffsetY) {
        self.toolBar.hidden = NO;
        [UIView animateWithDuration:0.4 animations:^{
            self.toolBarScrollStatus = QVToolBarScrollStatusAnimation;
            CGRect rect = self.toolBar.frame;
            self.toolBar.frame = CGRectMake(rect.origin.x,
                                            rect.origin.y - rect.size.height,
                                            rect.size.width,
                                            rect.size.height);
        } completion:^(BOOL finished) {
            self.toolBarScrollStatus = QVToolBarScrollStatusInit;
        }];
    }
}

ちなみに、初めに設定したSyntaxHighlighterのObjective-C用の設定はうまく適用されないので、後日設定し直さなければ・・・。