Skip to content

Instantly share code, notes, and snippets.

@lorenzoferrante
Created January 5, 2019 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lorenzoferrante/72318d9686d3a536a57bcfb0b784d54d to your computer and use it in GitHub Desktop.
Save lorenzoferrante/72318d9686d3a536a57bcfb0b784d54d to your computer and use it in GitHub Desktop.
UITableView stretchy header
import UIKit
class ViewController: UITableViewController {
private let kTableViewHeaderHeight: CGFloat = 300.0
var headerView: UIView!
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
headerView = tableView.tableHeaderView
tableView.tableHeaderView = nil
tableView.backgroundColor = UIColor.blackTheme
tableView.addSubview(headerView)
tableView.contentInset = UIEdgeInsets(top: kTableViewHeaderHeight,
left: 0,
bottom: 0,
right: 0)
tableView.contentOffset = CGPoint(x: 0,
y: -kTableViewHeaderHeight)
updateHeaderView()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let navButtonLeft = UIBarButtonItem(barButtonSystemItem: .done,
target: self,
action: nil)
let navButtonRight = UIBarButtonItem(barButtonSystemItem: .action,
target: self,
action: nil)
navigationItem.leftBarButtonItem = navButtonLeft
navigationItem.rightBarButtonItem = navButtonRight
let alphaImage = getImageFrom(color: UIColor.white.withAlphaComponent(0.0))
navigationController!.navigationBar.isTranslucent = true
navigationController!.navigationBar.barStyle = .blackTranslucent
navigationController!.navigationBar.tintColor = .white
navigationController!.navigationBar.setBackgroundImage(alphaImage!,
for: .default)
navigationController!.navigationBar.shadowImage = UIImage()
}
private func updateHeaderView() {
var headerRect = CGRect(x: 0,
y: -kTableViewHeaderHeight,
width: tableView.bounds.width,
height: kTableViewHeaderHeight)
if tableView.contentOffset.y < -kTableViewHeaderHeight {
headerRect.origin.y = tableView.contentOffset.y
headerRect.size.height = -tableView.contentOffset.y
}
headerView.frame = headerRect
}
}
extension ViewController {
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.updateHeaderView()
let offset = tableView.contentOffset.y + kTableViewHeaderHeight
if offset >= 100 && offset < kTableViewHeaderHeight {
let alpha = (offset * 1.0) / kTableViewHeaderHeight
let alphaImage = getImageFrom(color: UIColor.black.withAlphaComponent(alpha))!
navigationController!.navigationBar.setBackgroundImage(alphaImage, for: .compact)
navigationController!.navigationBar.setBackgroundImage(alphaImage, for: .default)
self.title = "Spider-Man"
} else if offset >= kTableViewHeaderHeight {
let alphaImage = getImageFrom(color: UIColor.black)!
navigationController!.navigationBar.setBackgroundImage(alphaImage, for: .compact)
navigationController!.navigationBar.setBackgroundImage(alphaImage, for: .default)
self.title = "Spider-Man"
} else {
let alphaImage = getImageFrom(color: UIColor.clear)!
navigationController!.navigationBar.setBackgroundImage(alphaImage, for: .compact)
navigationController!.navigationBar.setBackgroundImage(alphaImage, for: .default)
self.title = nil
}
}
}
extension ViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 50
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.backgroundColor = .clear
cell.textLabel?.text = "Cell \(indexPath.row+1)"
cell.textLabel?.textColor = .white
return cell
}
}
extension ViewController {
func getImageFrom(color: UIColor) -> UIImage? {
if let navigationBar = self.navigationController?.navigationBar {
let gradient = CAGradientLayer()
var bounds = navigationBar.bounds
bounds.size.height += UIApplication.shared.statusBarFrame.size.height
gradient.frame = bounds
gradient.colors = [color.cgColor, color.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1, y: 0)
var gradientImage:UIImage?
UIGraphicsBeginImageContext(gradient.frame.size)
if let context = UIGraphicsGetCurrentContext() {
gradient.render(in: context)
gradientImage = UIGraphicsGetImageFromCurrentImageContext()?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
}
UIGraphicsEndImageContext()
return gradientImage
}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment