ツイッターのように画面を下にスクロールした際に、画像が拡大するヘッダーを実装する機会があったので備忘録として書きます!
##完成形
TableViewを下に引っ張った際に画像を拡大させる。
##実装方法
AutoLayoutなど様々なやり方があると思いますが、今回はTableViewCellを使用した方法で実装していきます。
##①カスタムセルを用意する
適当なセルを用意してUIImgeViewをのせます。
StretchyHeaderTableViewCell.swift
import UIKit
final class StretchyHeaderTableViewCell: UITableViewCell {
@IBOutlet weak var headerImageView: UIImageView!
static var className: String {
return String(describing: self)
}
static var idetifier: String {
return className
}
static func nib() -> UINib {
return UINib(nibName: idetifier, bundle: nil)
}
func configure(headerImageUrl: String) {
headerImageView.image = UIImage(named: headerImageUrl)
}
}
##②TableViewへ登録する
上記で作成したカスタムセルをtableviewへ登録します。
##③制約を加える
StretchyHeaderViewController.swift
private var lastContentOffset = CGPoint.zero
StretchyHeaderViewController.swift
extension StretchyHeaderViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y <= 0.0 {
if let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) {
let deltaY = CGFloat(fabsf(Float(scrollView.contentOffset.y)) - fabsf(Float(lastContentOffset.y)))
cell.frame = CGRect(x: 0.0, y: scrollView.contentOffset.y, width: cell.frame.size.width, height: cell.frame.size.height + deltaY)
lastContentOffset = scrollView.contentOffset
}
}
}
##全体のコード
StretchyHeaderViewController.swift
import UIKit
final class StretchyHeaderViewController: UIViewController {
@IBOutlet private weak var tableView: UITableView!
private var lastContentOffset = CGPoint.zero
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.register(StretchyHeaderTableViewCell.nib(), forCellReuseIdentifier: StretchyHeaderTableViewCell.idetifier)
}
}
extension StretchyHeaderViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y <= 0.0 {
if let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) {
let deltaY = CGFloat(fabsf(Float(scrollView.contentOffset.y)) - fabsf(Float(lastContentOffset.y)))
cell.frame = CGRect(x: 0.0, y: scrollView.contentOffset.y, width: cell.frame.size.width, height: cell.frame.size.height + deltaY)
lastContentOffset = scrollView.contentOffset
}
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}
}
extension StretchyHeaderViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: StretchyHeaderTableViewCell.idetifier) as! StretchyHeaderTableViewCell
cell.configure(headerImageUrl: "curry")
return cell
}
}
##最後に
一見難しそうですがたったこれだけでツイッターライクなヘッダーが完成します。最近のアプリだとスクロール時に画像が拡大するものが多いのでぜひ参考にしてください!