Skip to content

Instantly share code, notes, and snippets.

@iamchiwon
Last active September 17, 2018 13:34
Show Gist options
  • Select an option

  • Save iamchiwon/4253b7c84bad223de8adde0b58eb752c to your computer and use it in GitHub Desktop.

Select an option

Save iamchiwon/4253b7c84bad223de8adde0b58eb752c to your computer and use it in GitHub Desktop.
Long-TableHeaderView Sample
//
// ViewController.swift
// TableViewExample
//
// Created by iamchiwon on 2018. 8. 2..
// Copyright © 2018년 ncode. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
import SnapKit
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setupEvents()
}
var tableView: UITableView!
var headerImage: UIImageView!
private var statusHeight: CGFloat {
return self.view.layoutMargins.top
}
private func setupViews() {
tableView = UITableView()
view.addSubview(tableView)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
tableView.snp.makeConstraints({ m in
m.edges.equalToSuperview()
})
let headerView = UIStackView()
tableView.tableHeaderView = headerView
headerView.axis = .vertical
headerView.snp.makeConstraints({ m in
m.top.equalToSuperview().offset(-self.statusHeight)
m.width.centerX.equalToSuperview()
})
let titleImage = UIView()
headerView.addArrangedSubview(titleImage)
titleImage.snp.makeConstraints({ m in
m.height.equalTo(0)
})
let titleImageView = UIImageView()
titleImage.addSubview(titleImageView)
titleImageView.contentMode = .scaleAspectFill
titleImageView.snp.makeConstraints({ m in
m.width.centerX.top.equalToSuperview()
m.height.equalTo(0)
})
headerImage = titleImageView
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
do {
let url = URL(string: "http://photo.hankooki.com/newsphoto/v001/2017/12/26/dyhero21320171226011858_O_01_C_1.jpg")
let data = try Data(contentsOf: url!)
let image = UIImage(data: data)!
titleImageView.image = image
let width = image.size.width
let height = image.size.height
let screenWidth = UIScreen.main.bounds.width
let ratioHeight = screenWidth * height / width
titleImage.snp.updateConstraints({ m in
m.height.equalTo(ratioHeight)
})
titleImageView.snp.updateConstraints({ m in
m.height.equalTo(ratioHeight + self.statusHeight)
})
self.updateHeaderView()
} catch { }
}
let content1 = UIView()
content1.backgroundColor = UIColor.lightGray
addHeaderView(content1, 100)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
let content2 = UIView()
content2.backgroundColor = UIColor.yellow
self.addHeaderView(content2, 200)
self.updateHeaderView()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
let content3 = UIView()
content3.backgroundColor = UIColor.red
self.addHeaderView(content3, 150)
self.updateHeaderView()
}
}
private func updateHeaderView() {
tableView.tableHeaderView?.layoutIfNeeded()
let headerView = tableView.tableHeaderView
tableView.tableHeaderView = headerView
}
private func addHeaderView(_ view: UIView, _ height: CGFloat) {
(tableView.tableHeaderView as? UIStackView)?.addArrangedSubview(view)
view.snp.makeConstraints({ m in
m.height.equalTo(height)
})
}
private func setupEvents() {
tableView.rx.didScroll.map({ _ in self.tableView }).filter { $0 != nil }.map { $0! }
.subscribe(onNext: { tableView in
print("inset : \(tableView.contentInset)")
print("screen offset : \(tableView.contentOffset)")
let offY = tableView.contentOffset.y
let addHeight = offY < 0 ? abs(offY) : 0
let imgSize = self.headerImage.image?.size ?? CGSize(width: 1, height: 1)
let screenWidth = UIScreen.main.bounds.width
let ratioHeight = screenWidth * imgSize.height / imgSize.width + addHeight
self.headerImage.snp.updateConstraints({ m in
m.top.equalToSuperview().offset(-addHeight)
m.height.equalTo(ratioHeight)
})
})
.disposed(by: disposeBag)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
let content = "CELL \(indexPath.row)"
cell.textLabel?.text = content
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment