Customizing the Navigation Bar and MVC Implementation
YouTubeWelcome back all! Today, let's finish up the layout for each of our video cells first. Then we'll move onto customizing the navigation bar to closely match our YouTube app. Finally lets clean up some of the code to better reflect general MVC structuring.
<div class='filename'>HomeController.swift</div>
!codebreak
!syntax-highlight
class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Home"
navigationController?.navigationBar.translucent = false
let titleLabel = UILabel(frame: CGRectMake(0, 0, view.frame.width - 32, view.frame.height))
titleLabel.text = "Home"
titleLabel.textColor = UIColor.whiteColor()
titleLabel.font = UIFont.systemFontOfSize(20)
navigationItem.titleView = titleLabel
collectionView?.backgroundColor = UIColor.whiteColor()
collectionView?.registerClass(VideoCell.self, forCellWithReuseIdentifier: "cellId")
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellId", forIndexPath: indexPath)
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let height = (view.frame.width - 16 - 16) * 9 / 16
return CGSizeMake(view.frame.width, height + 16 + 68)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
}
!codebreak
<div class='filename'>UIColor extension</div>
!codebreak
!syntax-highlight
extension UIColor {
static func rgb(red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor {
return UIColor(red: red/255, green: green/255, blue: blue/255, alpha: 1)
}
}
!codebreak
<div class='filename'>UIView</div>
!codebreak
!syntax-highlight
extension UIView {
func addConstraintsWithFormat(format: String, views: UIView...) {
var viewsDictionary = [String: UIView]()
for (index, view) in views.enumerate() {
let key = "v\(index)"
view.translatesAutoresizingMaskIntoConstraints = false
viewsDictionary[key] = view
}
addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
}
!codebreak
<div class='filename'>AppDelegate</div>
!codebreak
!syntax-highlight
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.makeKeyAndVisible()
let layout = UICollectionViewFlowLayout()
window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))
UINavigationBar.appearance().barTintColor = UIColor.rgb(230, green: 32, blue: 31)
application.statusBarStyle = .LightContent
let statusBarBackgroundView = UIView()
statusBarBackgroundView.backgroundColor = UIColor.rgb(194, green: 31, blue: 31)
window?.addSubview(statusBarBackgroundView)
window?.addConstraintsWithFormat("H:|[v0]|", views: statusBarBackgroundView)
window?.addConstraintsWithFormat("V:|[v0(20)]", views: statusBarBackgroundView)
return true
}
!codebreak
<div class='filename'>VideoCell.swift</div>
!codebreak
!syntax-highlight
class VideoCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
let thumbnailImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "taylor_swift_blank_space")
imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
let userProfileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "taylor_swift_profile")
imageView.layer.cornerRadius = 22
imageView.layer.masksToBounds = true
return imageView
}()
let separatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1)
return view
}()
let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Taylor Swift - Blank Space"
return label
}()
let subtitleTextView: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.text = "TaylorSwiftVEVO • 1,604,684,607 views • 2 years ago"
textView.textContainerInset = UIEdgeInsetsMake(0, -4, 0, 0)
textView.textColor = UIColor.lightGrayColor()
return textView
}()
func setupViews() {
addSubview(thumbnailImageView)
addSubview(separatorView)
addSubview(userProfileImageView)
addSubview(titleLabel)
addSubview(subtitleTextView)
addConstraintsWithFormat("H:|-16-[v0]-16-|", views: thumbnailImageView)
addConstraintsWithFormat("H:|-16-[v0(44)]", views: userProfileImageView)
//vertical constraints
addConstraintsWithFormat("V:|-16-[v0]-8-[v1(44)]-16-[v2(1)]|", views: thumbnailImageView, userProfileImageView, separatorView)
addConstraintsWithFormat("H:|[v0]|", views: separatorView)
//top constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Top, relatedBy: .Equal, toItem: thumbnailImageView, attribute: .Bottom, multiplier: 1, constant: 8))
//left constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Left, relatedBy: .Equal, toItem: userProfileImageView, attribute: .Right, multiplier: 1, constant: 8))
//right constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Right, relatedBy: .Equal, toItem: thumbnailImageView, attribute: .Right, multiplier: 1, constant: 0))
//height constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Height, relatedBy: .Equal, toItem: self, attribute: .Height, multiplier: 0, constant: 20))
//top constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Top, relatedBy: .Equal, toItem: titleLabel, attribute: .Bottom, multiplier: 1, constant: 4))
//left constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Left, relatedBy: .Equal, toItem: userProfileImageView, attribute: .Right, multiplier: 1, constant: 8))
//right constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Right, relatedBy: .Equal, toItem: thumbnailImageView, attribute: .Right, multiplier: 1, constant: 0))
//height constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Height, relatedBy: .Equal, toItem: self, attribute: .Height, multiplier: 0, constant: 30))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}