Login required for access
In order to watch this lesson, you'll need to login to the website.
Model View Controller Pattern Explained
YouTube
Lets go over one of the most common design patterns we see in iOS development: MVC. So far we've been writing all of our code in views and controllers, so now lets complete the implementation by writing our model objects. We'll create video and channel models to continue making progress in our YouTube application.
<div class='filename'>VideCell.swift</div> !codebreak !syntax-highlight import UIKit class Video: NSObject { var thumbnailImageName: String? var title: String? var numberOfViews: NSNumber? var uploadDate: NSDate? var channel: Channel? } class Channel: NSObject { var name: String? var profileImageName: String? } !codebreak <div class='filename'>VideoCell.swift</div> !codebreak !syntax-highlight class VideoCell: BaseCell { var video: Video? { didSet { titleLabel.text = video?.title thumbnailImageView.image = UIImage(named: (video?.thumbnailImageName)!) if let profileImageName = video?.channel?.profileImageName { userProfileImageView.image = UIImage(named: profileImageName) } if let channelName = video?.channel?.name, numberOfViews = video?.numberOfViews { let numberFormatter = NSNumberFormatter() numberFormatter.numberStyle = .DecimalStyle let subtitleText = "\(channelName) • \(numberFormatter.stringFromNumber(numberOfViews)!) • 2 years ago " subtitleTextView.text = subtitleText } //measure title text if let title = video?.title { let size = CGSizeMake(frame.width - 16 - 44 - 8 - 16, 1000) let options = NSStringDrawingOptions.UsesFontLeading.union(.UsesLineFragmentOrigin) let estimatedRect = NSString(string: title).boundingRectWithSize(size, options: options, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(14)], context: nil) if estimatedRect.size.height > 20 { titleLabelHeightConstraint?.constant = 44 } else { titleLabelHeightConstraint?.constant = 20 } } } } 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" label.numberOfLines = 2 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 }() var titleLabelHeightConstraint: NSLayoutConstraint? override 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)]-36-[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 titleLabelHeightConstraint = NSLayoutConstraint(item: titleLabel, attribute: .Height, relatedBy: .Equal, toItem: self, attribute: .Height, multiplier: 0, constant: 44) addConstraint(titleLabelHeightConstraint!) //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)) } } !codebreak <div class='filename'>HomeController.swift</div> !codebreak !syntax-highlight class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout { var videos: [Video] = { var kanyeChannel = Channel() kanyeChannel.name = "KanyeIsTheBestChannel" kanyeChannel.profileImageName = "kanye_profile" var blankSpaceVideo = Video() blankSpaceVideo.title = "Taylor Swift - Blank Space" blankSpaceVideo.thumbnailImageName = "taylor_swift_blank_space" blankSpaceVideo.channel = kanyeChannel blankSpaceVideo.numberOfViews = 23932843093 var badBloodVideo = Video() badBloodVideo.title = "Taylor Swift - Bad Blood featuring Kendrick Lamar" badBloodVideo.thumbnailImageName = "taylor_swift_bad_blood" badBloodVideo.channel = kanyeChannel badBloodVideo.numberOfViews = 57989654934 return [blankSpaceVideo, badBloodVideo] }() 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") collectionView?.contentInset = UIEdgeInsetsMake(50, 0, 0, 0) collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(50, 0, 0, 0) setupMenuBar() setupNavBarButtons() } func setupNavBarButtons() { let searchImage = UIImage(named: "search_icon")?.imageWithRenderingMode(.AlwaysOriginal) let searchBarButtonItem = UIBarButtonItem(image: searchImage, style: .Plain, target: self, action: #selector(handleSearch)) let moreButton = UIBarButtonItem(image: UIImage(named: "nav_more_icon")?.imageWithRenderingMode(.AlwaysOriginal), style: .Plain, target: self, action: #selector(handleMore)) navigationItem.rightBarButtonItems = [moreButton, searchBarButtonItem] } func handleMore() { } func handleSearch() { print(123) } let menuBar: MenuBar = { let mb = MenuBar() return mb }() private func setupMenuBar() { view.addSubview(menuBar) view.addConstraintsWithFormat("H:|[v0]|", views: menuBar) view.addConstraintsWithFormat("V:|[v0(50)]", views: menuBar) } override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return videos.count } override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellId", forIndexPath: indexPath) as! VideoCell cell.video = videos[indexPath.item] 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 + 88) } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat { return 0 } }

Comments (7)
7 years ago
4 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
6 years ago
6 years ago
8 years ago
7 years ago
HELP & SUPPORT