Creating our own Custom Tab Bar Menu Bar
YouTubeWelcome back fellow App Builders. We're making solid progress on the YouTube app so lets continue by creating the custom MenuBar that is anchored below our navigation bar. Instead of using a UISegmentedControl like you'd might expect, we're going to create this component using a UICollectionView. Sit back, enjoy, and have some fun learning today.
<div class='filename'>MenuBar.swift</div>
!codebreak
!syntax-highlight
class MenuBar: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.rgb(230, green: 32, blue: 31)
cv.dataSource = self
cv.delegate = self
return cv
}()
let cellId = "cellId"
let imageNames = ["home", "trending", "subscriptions", "account"]
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.registerClass(MenuCell.self, forCellWithReuseIdentifier: cellId)
addSubview(collectionView)
addConstraintsWithFormat("H:|[v0]|", views: collectionView)
addConstraintsWithFormat("V:|[v0]|", views: collectionView)
let selectedIndexPath = NSIndexPath(forItem: 0, inSection: 0)
collectionView.selectItemAtIndexPath(selectedIndexPath, animated: false, scrollPosition: .None)
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId, forIndexPath: indexPath) as! MenuCell
cell.imageView.image = UIImage(named: imageNames[indexPath.item])?.imageWithRenderingMode(.AlwaysTemplate)
cell.tintColor = UIColor.rgb(91, green: 14, blue: 13)
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(frame.width / 4, frame.height)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
!codebreak
<div class='filename'>MenuCell.swift</div>
!codebreak
!syntax-highlight
class MenuCell: BaseCell {
let imageView: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named: "home")?.imageWithRenderingMode(.AlwaysTemplate)
iv.tintColor = UIColor.rgb(91, green: 14, blue: 13)
return iv
}()
override var highlighted: Bool {
didSet {
imageView.tintColor = highlighted ? UIColor.whiteColor() : UIColor.rgb(91, green: 14, blue: 13)
}
}
override var selected: Bool {
didSet {
imageView.tintColor = selected ? UIColor.whiteColor() : UIColor.rgb(91, green: 14, blue: 13)
}
}
override func setupViews() {
super.setupViews()
addSubview(imageView)
addConstraintsWithFormat("H:[v0(28)]", views: imageView)
addConstraintsWithFormat("V:[v0(28)]", views: imageView)
addConstraint(NSLayoutConstraint(item: imageView, attribute: .CenterX, relatedBy: .Equal, toItem: self, attribute: .CenterX, multiplier: 1, constant: 0))
addConstraint(NSLayoutConstraint(item: imageView, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: 1, constant: 0))
}
}
!codebreak
<div class='filename'>BaseCell.swift</div>
!codebreak
!syntax-highlight
class BaseCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
func setupViews() {
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}