More than 1 year has passed since last update.

やること

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
        }
}

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