tableViewのheaderというか上部を、下にスクロールした時は固定で、上にやったら上に行くサンプル


こんなデザインはよくみると思うのですが、どうやるのが良いのか正解はよくわからずですが。自分なりには、これがシンプルな実装かと思っております。

最初は、UITableViewのtableHeaderViewを使って、どうにか実装しようと思ったのですが、ぜんぜんわからず。それは使わずに、『単純に、tableViewの上にオリジナルで作成したUIViewを乗せる』という方法になっております。

『スクロール時の座標計算でヘッダーを固定』するというのがポイントです。

ViewController.swift
import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var myTableView: UITableView!
    var myItems: NSMutableArray = []
    var myHeaderView: UIView!

    var statusBarHeight: CGFloat!
    var displayWidth: CGFloat!
    var displayHeight: CGFloat!

    /*
    ロード後
    */
    override func viewDidLoad() {
        super.viewDidLoad()

        self.setItem()

        statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
        displayWidth = self.view.frame.width
        displayHeight = self.view.frame.height

        // テーブル
        myTableView = UITableView(frame: CGRect(x: 0, y: statusBarHeight, width: displayWidth, height: displayHeight))
        myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        myTableView.dataSource = self
        myTableView.delegate = self
        myTableView.contentInset.top = 100 //(★..コンテンツをヘッダー高さ分下げる)
        self.view.addSubview(myTableView)

        // オリジナルヘッダービューを作成
        myHeaderView = UIView(frame: CGRect(x: 0, y: -100, width: displayHeight, height: 100)) //(★..コンテンツの上にヘッダーを配置)
        myHeaderView.backgroundColor = UIColor.greenColor()
        myHeaderView.alpha = 0.5
        myTableView.addSubview(myHeaderView)
        let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: displayWidth, height: 50))
        myLabel.text = "高さ100のオリジナルヘッダービュー"
        myLabel.font = UIFont.systemFontOfSize(12)
        myLabel.textAlignment = .Center
        myHeaderView.addSubview(myLabel)
    }

    /*
    アイテムをただ用意するだけ
    */
    func setItem() {
        for index in 1...18 {
            self.myItems.addObject("Item\(index)")
        }
    }

    /*
    テーブル行数
    */
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.myItems.count
    }

    /*
    テーブルセルの設定
    */
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
        cell.textLabel?.text = self.myItems[indexPath.row] as? String
        return cell
    }

    /*
    スクロール時
    */
    func scrollViewDidScroll(scrollView: UIScrollView) {

        // 下に引っ張ったときは、ヘッダー位置を計算して動かないようにする(★ここがポイント..)
        if scrollView.contentOffset.y < -100 {
            self.myHeaderView.frame = CGRect(x: 0, y: scrollView.contentOffset.y, width: self.displayWidth, height: 100)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}