
This video is only available to subscribers. Start a subscription today to get access to this and 477 other videos.
TableView Customization
Episode Links
Setting up Colors and Fonts for Easy Re-use
It's not easy sharing colors & font settings between Storyboards and Code, so we'll do the majority of our customization in code.
struct Theme {
enum Colors {
case TintColor
case BackgroundColor
case DarkBackgroundColor
case SectionHeader
case Foreground
case LightTextColor
var color: UIColor {
switch self {
case .TintColor: return UIColor(red:0.97, green:0.9, blue:0, alpha:1)
case .BackgroundColor: return UIColor(hue:0.67, saturation:0.37, brightness:0.35, alpha:1)
case .DarkBackgroundColor: return UIColor(red:0.11, green:0.1, blue:0.22, alpha:1)
case .SectionHeader: return UIColor(hue:0.67, saturation:0.4, brightness:0.25, alpha:1)
case .Foreground: return UIColor(red:0.26, green:0.25, blue:0.37, alpha:1)
case .LightTextColor: return UIColor(red:0.64, green:0.65, blue:0.8, alpha:1)
}
}
}
enum Fonts {
case TitleFont
case BoldTitleFont
var font: UIFont {
switch self {
case .BoldTitleFont: return UIFont(name: "Copperplate-Bold", size: 17)!
case .TitleFont: return UIFont(name: "Copperplate", size: 16)!
}
}
}
}
With this in place we can easily reference our colors and fonts from anywhere. Updating the styles for further tweaking is as simple as modifying Theme.swift
.
Setting Global Styles
In AppDelegate.swift
:
window?.tintColor = Theme.Colors.TintColor.color
let navBarAppearance = UINavigationBar.appearance()
navBarAppearance.titleTextAttributes = [
NSFontAttributeName: Theme.Fonts.BoldTitleFont.font,
NSForegroundColorAttributeName: Theme.Colors.TintColor.color
]
navBarAppearance.barStyle = UIBarStyle.Black
navBarAppearance.barTintColor = Theme.Colors.Foreground.color
Initial Table View Tweaks
In viewDidLoad
we can set our colors, as well as removing the fake repeating cells that occur at the bottom of a .Plain
-styled UITableView
:
tableView.separatorColor = Theme.Colors.DarkBackgroundColor.color
tableView.backgroundColor = Theme.Colors.BackgroundColor.color
tableView.tableFooterView = UIView()
Custom Race Header View
Instead of the standard section headers, we'll implement our own view:
class RaceHeaderView : UIView {
var imageView: UIImageView!
var label: UILabel!
convenience init() {
self.init(frame: CGRectZero)
}
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupSubviews()
}
func setupSubviews() {
backgroundColor = Theme.Colors.SectionHeader.color
imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = UIViewContentMode.Center
addSubview(imageView)
imageView.centerYAnchor.constraintEqualToAnchor(centerYAnchor).active = true
imageView.leftAnchor.constraintEqualToAnchor(leftAnchor, constant: 20).active = true
label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Theme.Fonts.BoldTitleFont.font
label.textColor = Theme.Colors.TintColor.color
addSubview(label)
label.leftAnchor.constraintEqualToAnchor(imageView.rightAnchor, constant: 20).active = true
label.centerYAnchor.constraintEqualToAnchor(imageView.centerYAnchor).active = true
}
}
Then we can vend this view in our controller when our table view asks for it:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = RaceHeaderView()
let race = self.tableView(tableView, titleForHeaderInSection: section)!
header.label.text = race
header.imageView.image = UIImage(named: race.lowercaseString)!
return header
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 66
}
Removing the Default Separator Margin
I never understood the rationale behind the cell separator indent. It looks okay for a stock look & feel, but often looks wrong when you start changing styles. We can remove this in our custom cell subclass:
class GuideCell : UITableViewCell {
static let reuseIdentifier = "GuideCell"
@IBOutlet weak var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
backgroundColor = Theme.Colors.Foreground.color
nameLabel.font = Theme.Fonts.TitleFont.font
nameLabel.textColor = Theme.Colors.LightTextColor.color
separatorInset = UIEdgeInsetsZero
layoutMargins = UIEdgeInsetsZero
}
}
You can also choose to do this in the controller itself, if all cells need to have the same effect applied:
func tableView(_ tableView: UITableView,
willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
}
And with that, we've customized the theme quite a bit!
Credits
Icons were obtained from the Starcraft Wikia.