109
108

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UIWebViewの上下フリックでツールバーを表示したりしなかったり

Posted at

SmartNewsやPintrestを見ているとスクロールに応じてツールバー(もしくはタブ)を表示したりしなかったりしている。

これは、UIWebViewの下を見ようとフリックしていく際にはツールバーを消し、逆に上を見ようとフリックした際にはツールバーを表示していて、iPhoneの狭い画面でもなるべく広く使うためのテクニックになっている。

↑このツールバーは常に表示する必要がないので出したり出さなかったり

仕様をまとめる

  • 画面の下を見ようとする動作でツールバー消す

  • 上に向けてフリック

  • スクロール後のy軸オフセット値がスクロール前より増える

  • =>スクロールビューのdelegateでオフセット値を計算

  • => scrollViewWillBeginDragging:でスクロールし始めを取得

  • => scrollViewDidScroll:でスクロール後に増えてたら消す

  • 画面の上に戻ろうとする動作でツールバーを表示

  • 下に向けてフリック

  • スクロール後のy軸オフセット値がスクロール前より減る

  • =>スクロールビューのdelegateでオフセット値を計算

  • => scrollViewWillBeginDragging:でスクロールし始めを取得

  • => scrollViewDidScroll:でスクロール後に増えてたら表示

  • ツールバーはアニメーションで消す

  • すでにアニメーションが行われていれば割り込まない

  • =>フラグもしくは列挙体でステータスを制御

コード

スクロールのステータスを表すenumを用意しておく

typedef enum {
    QVToolBarScrollStatusInit = 0,
    QVToolBarScrollStatusAnimation ,
}QVToolBarScrollStatus;

スクロールしはじめのオフセット値を保持するプロパティを用意

@property(nonatomic) CGFloat beginScrollOffsetY;

UIScrollViewのdelegateを実装して計算

//スクロールビューをドラッグし始めた際に一度実行される
- (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;
        }];
    }
}
109
108
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
109
108

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?