Created
January 5, 2019 00:30
-
-
Save lorenzoferrante/72318d9686d3a536a57bcfb0b784d54d to your computer and use it in GitHub Desktop.
UITableView stretchy header
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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