LoginSignup
56

More than 5 years have passed since last update.

WebViewのスクロールで、toolbarやnavigationBarを隠す

Last updated at Posted at 2015-08-14

やること

WebViewをスクロールして下げていくとtoolbarを隠し
上げると表示させる機能を実装したいと思います。

はじめに

NavigationControlerをトップにつけます。

デフォルトで、表示されているViewControllerを選択し

Xcodeのメニューから

Editor → Embed In → Navigation Contoroller で追加できます。

1.png

追加後に、Shows Toolbarにチェックを入れます。

2.png

これで、デフォルトのViewControllerにtoolbarが追加されました。

WebViewのスクロールイベントを取得する

WebViewには、iOS5からscrollViewが子クラスとして設定されているので、そいつのデリゲートを取得する

ViewController.swift

import UIKit

class ViewController: UIViewController, UIWebViewDelegate, UIScrollViewDelegate {

    @IBOutlet weak var webView: UIWebView!

    var beginingPoint: CGPoint!
    var isViewShowed: Bool!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 各種初期化
        isViewShowed = false
        beginingPoint = CGPoint(x: 0, y: 0)
        webView.delegate = self
        webView.scrollView.delegate = self

        // とりあえず、Google表示してみる
        let url: NSURL = NSURL(string:"https://www.google.co.jp/")
        webView.loadRequest(NSURLRequest(URL:url))
    }

    override func viewDidAppear(animated: Bool) {
        isViewShowed = true
    }

    // WebViewをスクロールする際に開始時の値をセット
    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        beginingPoint = scrollView.contentOffset
    }

    // WebViewのスクロールイベント取得 開始時の値と比較してToolbarを表示・非表示
    func scrollViewDidScroll(scrollView: UIScrollView) {
        var currentPoint = scrollView.contentOffset
        var contentSize = scrollView.contentSize
        var frameSize = scrollView.frame
        var maxOffSet = contentSize.height - frameSize.height

        if isViewShowed == true && currentPoint.y < maxOffSet {
            self.navigationController?.setToolbarHidden(true, animated: true)
        } else {
            self.navigationController?.setToolbarHidden(false, animated: true)
        }
    }
}

これで、上にスクロールしている時は非表示。下にスクロールしている時は表示になると思います。

contentOffsetと比較を行うことで、最後までスクロールした際にbounceを付けていた場合、toolbarがガタガタと動作がおかしくなります。bounceを切ってもいいんですが、UIRefreshControlを使って更新(下に引っ張って更新)を行いたいのでこのような形になりました。

追記

@sassymanyuichiさんから頂いたコメントのように

func scrollViewDidScroll(scrollView: UIScrollView) {
    let currentPoint = scrollView.contentOffset
    let contentSize = scrollView.contentSize
    let frameSize = scrollView.frame
    let maxOffSet = contentSize.height - frameSize.height

    if currentPoint.y >= maxOffSet {
        print("hit the bottom")
        self.navigationController?.setToolbarHidden(true, animated: true)
    } else if scrollBeginingPoint.y < currentPoint.y {
        //print("Scrolled down")
        self.navigationController?.setToolbarHidden(true, animated: true)
    }else{
        //print("Scrolled up")
        self.navigationController?.setToolbarHidden(false, animated: true)
    }
}

のように実装すると、スムーズにスクロールできます。

NavigationBarを隠す場合

func scrollViewDidScroll(scrollView: UIScrollView) {
        let currentPoint = scrollView.contentOffset
        let contentSize = scrollView.contentSize
        let frameSize = scrollView.frame
        let maxOffSet = contentSize.height - frameSize.height

        if currentPoint.y >= maxOffSet {
            print("hit the bottom")
            navigationController?.hidesBarsOnSwipe = true
        } else if beginingPoint.y < currentPoint.y {
            //print("Scrolled down")
            navigationController?.hidesBarsOnSwipe = true
        }else{
            //print("Scrolled up")
            // NavigationBarを表示
            navigationController?.navigationBarHidden = false
            navigationController?.hidesBarsOnSwipe = false
        }
}

このような感じでいけます。

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
56