SwiftUI 2 - Build Netflix Clone - iOS 14 - Xcode 12 - UPDATED | Nikita Thomas | Skillshare

Playback Speed

  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

SwiftUI 2 - Build Netflix Clone - iOS 14 - Xcode 12 - UPDATED

teacher avatar Nikita Thomas, iOS Software Engineer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

41 Lessons (11h 1m)
    • 1. Course Intro

    • 2. Creating an Xcode project for SwiftUI

    • 3. Setting up HomeView

    • 4. Large Movie Preview Part 1

    • 5. Large Movie Preview Part 2

    • 6. Large Movie Preview Part 3

    • 7. Large Movie Preview Part 4

    • 8. HomeView top row of buttons

    • 9. Building MovieDetail View Part 1

    • 10. Building MovieDetail View Part 2

    • 11. Building MovieDetail View Part 3

    • 12. Building MovieDetail View Part 4

    • 13. Custom Tab Switcher

    • 14. "More Like This" Grid

    • 15. "Trailers & More" List

    • 16. Episodes View Part 1

    • 17. Episodes View Part 2

    • 18. Episodes View Part 3

    • 19. Integrating MovieDetail View with our Home View

    • 20. Top Row Buttons (Part 1 - Setting State Variables)

    • 21. Top Row Buttons (Part 2 - Responding To State Variables)

    • 22. Top Row Buttons (Part 3 - Showing Overlay Menus)

    • 23. Building A TabView

    • 24. Custom Search Bar Part 1

    • 25. Custom Search Bar Part 2

    • 26. Search View Part 1

    • 27. Search View Part 2 - Custom Bindings

    • 28. Search View Part 3 - Popular

    • 29. Search View Part 4 - Lazy Grid

    • 30. Coming Soon Part 1

    • 31. Coming Soon (Part 2 - Tracking Scroll View)

    • 32. Downloads View

    • 33. Fix #1: Stretched Images

    • 34. Building "Preview Image Cell" View

    • 35. Building "Preview Row"

    • 36. Building the "Pager" - Scrollable Container of Views

    • 37. Trailer Player View - Video Player Wrapper

    • 38. Preview View - FullScreen video playing view

    • 39. PreviewList - Scrollable list of videos

    • 40. Advanced Drag Gesture 1 - Showing & Hiding a fullscreen overlay

    • 41. Advanced Drag Gesture 2 - Combining Multiple Gestures

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class


Building real apps is always the most efficient way to quickly learn new software engineering concepts. In this course you will learn how to use SwiftUI 2 for more than just playing with small prototypes.

You will be building a functional Netflix clone that has most of the features of the real app. The focus of this course is learning & perfecting SwiftUI concepts. We will be building all of the visual UI components from the Netflix app. We won’t handle networking and we’ll be loading our data locally to show up within the UI. The app is built with MVVM and you'll be able to easily integrate your own networking layer.

Some parts of the course require iOS 14 and Xcode 12.

Many lessons can be followed using Xcode 11 and the important concepts learned will still apply to iOS 13. But some views & functionality are only available in iOS 14 using Xcode 12. For example, the ‘Grid’ view is only availably in iOS 14+. For iOS 13, you would have to build your own implementation using a combination of VStacks & HStack.

What is SwiftUI 2? 
Apple has provided this new framework as a way to quickly build beautiful user interfaces for any Apple device using just one set of easy-to-use tools. With the new declarative syntax of SwiftUI, it takes less code to keep your code and design perfectly in sync.

SwiftUI works seamlessly with new Xcode design tools and significantly speeds up development by showing your code changes in real time! 

After the latest features for iOS 14 announced at WWDC 2020, SwiftUI 2 is even more robust! New views, new functionality, less bugs, and faster performance.

No excuses to skip out on SwiftUI 2 now.
Start learning today! 

This course is in no way affiliated with Netflix, Inc. No source code of the real Netflix application is ever shown. This code is my interpretation of how I would build the app using SwiftUI 2.

Who this course is for:

  • Experienced developers ready to jump into SwiftUI 2
  • Beginner developers learning how to build real applications with SwiftUI 2
  • Developers looking to practice their design skills
  • Developers who learn best by building real project

Meet Your Teacher

Teacher Profile Image

Nikita Thomas

iOS Software Engineer


Hi! I'm Nikita and I'm an iOS Engineer currently working in a large (15k+ employees) tech startup in San Francisco, California.

I have been fascinated with Swift every since Apple announced their new language in 2014. I have been learning through tons of online resources and have been using it every day at work ever since.

I love brining unique experiences to users through beautiful iOS applications.

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.


1. Course Intro: Hello and welcome to the build Netflix clone with Swift UI course. In this course, you will learn how to build a working clone of the Netflix application using the latest Swift Y2. And all of the really cool stuff that was announced for it at WWDC 2020. So for some of the new stuff that's announced that we will be going in depth into. We have the SF symbols too. There's a lot of new V stack and stack behaviors. Grids are very important for how Netflix uses them. And then the main benefit of this course is you'll be learning how to use everything within Swift UI to vote a real application. I think taking this course is very important to anybody looking to really accelerate their learning of Swift UI. This actually applies to a lot of new software engineering concepts, which is you learn best by building real projects. There is only so much you can learn by following small tutorials that isolate a certain feature and show you small perfect examples when it comes to Swift UI, there's two important skills. One is actually building the views. So that's how to build the views style, then position them on the screen and how to use frames, things like that. And the second thing is how to organize your data and pass it around the app. And this is the critical information that you gain by building a real project. So for this course, we'll be taking a look at the real Netflix application that you can find in the App Store. And we're going to start building it out screen by screen using Swift UI. You're going to learn how to build all of these small views that make up the app. Some of them are very simple. We'll start with those. And some of them are very complex with animations and custom transitions and will eventually cover everything there. You'll also learn how to combine these small views to actually build out these complex screens. So this is what's really great about course like this is you will start seeing all of your work coming together and piece-by-piece, we will start having a UI that looks really, really close to the real Netflix app. And then you'll also learn how to correctly organize your data and pass it around efficiently. With Swift UI, you'll become a master at using state, passing on bindings using observable objects, environment objects. All of this will come easy to you once we are done with the course and download the app, you will walk away with a strong understanding of the fundamentals of software. You will understand how to break down complex screens into a container of simple views. Along the way, you'll also learn tips and tricks specific to Swift UI that will speed up your development time and help you avoid common pitfalls when you're working on your next projects. And since this is a real app, you'll also walk away with lots of helpful extensions and reasonable views that you can carry over to your other swift UI projects. So I highly recommend you have two monitors for this course so that you can watch the lesson on one code along in real-time on a second monitor. You'll have a second monitor. You can just play the lessons on your iPad or a laptop or a second computer, but you will definitely learn so much more by actually getting your fingers on the keyboard and building out the app yourself. So that's it for the intro. I'm ready to get started with the first lesson. 2. Creating an Xcode project for SwiftUI: So in this video, we're going to cover creating the project. And this video was actually recorded after the entire course was complete. And all of the beta versions of Xcode 12 are done. And now that we have the official release version, what happens is when you create a new project on something like Xcode 12.1, your files are going to look a little bit different than how they look in the course. So I'm making this video to explain the process of creating a new project and explain the differences in what you're going to see on your latest version of Xcode 20 compared to what you're going to see in the videos. So as you can see in the videos, you're going to see a shared and an iOS folder. There's also going to be a macOS and products, but these are going to be mostly empty. And just for a couple of files, the shared is just going to contain our app, the content view, and our assets. And then all of the files that we're actually building are in this iOS folder. And you can see we have no AppDelegate war scene delegate. Instead we have the file that's named after our project. So build a Netflix app and we have this at main struct. That's basically just loading our content view. So let's cover the process of creating a new project. We're going to go up to File New Project. And we're going to see this screen. Now right away. It's going to be a little bit different than what's in the course. So in the course we actually made a multi-platform app. That's no longer the case. So now in multi-platform, there's just a game and Swift packages for frameworks. You're going to select iOS, and here you will select App. So this was different in the Xcode 12 beta before the official release. So that's why there's that shared and iOS folder. You're just going to create iOS app. Click Next, you're going to name it whatever you want. So I'll just say build Netflix two, that's gonna be our product name. This is just your developer account. So you should probably just have one personal team. Maybe if you work for a company, you'll have multiple options here. So your organization identifier is used to build your bundle identifier. And the common way to do this is com dot your team. And you can see how it builds the bundle identifier to basically become com dot. And then key to Thomas, dots are product name. So whenever you change up here will change the ending, and whatever you change here will change the beginning. And then after that we have some important settings. So for interface, we obviously want Swift UI. There's two options here, the UI kit storyboards and swift UI. So if you select Storyboard, you're gonna get a UI kit storyboard, which is the older way of designing iOS applications. This course is specifically covering Swift UI. So you want a 100 percent wanna make sure you have Swift UI selected here. You technically can select either one and build the other way. So you can select Swift UI and still use storyboards. And you can select storyboards and still make swift UI views. This basically just starts out your interface using one or the other. So select Swift UI now lifecycle, this is another important change to keep in mind. So there are two options here. Once again, basically the swift UI newer way or the UIKit older way. The swift UI app version gives us this at main struct. And so this is the Swift UI lifecycle. You don't have an AppDelegate, you don't have a scene delegate. You have one at main struct, and that's going to have a window group loading into your content view. And your content view is just whatever Swift UI view that you want. So here we have something like this. Now the UIKit app delegate option is going to give you a scene delegate and an AppDelegate File. So if you have a scene delegate and an app delegate file, that means you probably should just recreate the project for this course because I don't cover how to launch a swift UI view from a scene delegates. So this is something that you can look up. You definitely can just use a appDelegate, but you will have to look up on your own how to implement and how to load in a window group with a swift UI view from a UI kit seen delegates. So all of the functionality of the app delegate and the scene delegate can still be done using this swift UI app lifecycle. We don't cover it specifically in this course, but all of the functionality has just been moved over and there's just a different way to do it. And so you can look up how to do it. But to follow along with this course, these two options are what you want to see. You want to have Swift UI for the interface and swift UI app for the lifecycle for language. If you have these two options selected, there's only one swift because you can't use Objective-C or Swift UI. And then we don't use core data and we don't cover testing. But you definitely can check this. This will basically just create the targets for unit testing and UI testing. You can use this and mess around with the test or you can deselect it. This option won't really affect what you see in the course, so there shouldn't be confusion. What do you turn this on or off? But these are the settings that will get you as close as you can to the course that Let's click Next, and let's just save this into our folder here. So let's just take a look at the differences. You can see that in the project the way you'll see it in the course. We have our build Netflix project, and within that we have these four folders shared, iOS, MacOS, and products. Comparing that to the new project, this is what you will be seeing. You will see the project build Netflix two, and then you'll have two folders, one named after your project and one for products. So we can ignore products. This is not needed, but basically you just have one folder with all of your files in there. As opposed to the course, you'll see a MacOS folder and iOS folder and a shared folder. So to help clear up a little bit of confusion, all these folders within the project don't really matter per se. It's just a way of organizing your files. So even if you take a file and move it into Mac OS, it doesn't magically make that file only work for Mac OS. What really matters is this target membership on the side. So you can see this file is actually belonging to the target iOS and Mac OS. But it doesn't matter if it's in shared or iOS or MacOS folder. Target membership actually makes a difference. Now in your case when you create a new file here, you'll see that you should only have one target membership. So there should be no confusion there. And basically, you won't have an iOS or a shared folder, but you don't need one. You can have all of your files in the same structure just within this folder here. So you can, if you want to follow along a 100 percent with the course, you could just create a new folder called shared, a new folder called iOS and replicate this exact structure. So when you're following along with the course and it's time to create a new file. Just click on the Build Netflix folder instead of shared or iOS, make your new file there. So let's make our home view here. And you can see it's just within this large folder. And when we want to make a new folder, we can just do something like this. And so this is what it will look like. You'll have your folders here for home and model and search view all of your folders with all your views, not an iOS or shared. It's just going to be within this file here. And so this is what your structure is going to look like. All of your folders are just going to be within your project folder, not within iOS or shared. And once again, you should also be able to click on the file that is automatically generated. It's going to be the name of your project followed by app dot swift. This will have an AT main, same thing we have in the course window group of the content view. And then you'll have your content view created. And this you will follow perfectly with the course. We put our tab view into the content view. So just two takeaways from this video. One, if you're seeing app delegates and seen delegates, make sure you follow the settings on creating the Xcode project. And you create a project with the Swift UI app lifecycle that will make sure that you have this at main instead of an AppDelegate or seen delegate. And the second thing is when you create a project, you're just going to have one folder named after your project. And that's where all your folders and files are gonna go. You're not going to see iOS and shared. And when you're falling along with the course and you see me put a file into iOS or into shared. You know, you can just put it into your main folder and it's not going to make a difference. The content of the courses is still going to be worked perfectly. 3. Setting up HomeView: Hello and welcome to the first lesson. So as you can see, we have just created a brand new project in Xcode 12-bit item we selected to make an app. And this is the screen that we start with. This is the new Xcode 12 setup for Swift UI applications. So no longer are we setting a screen to the window in the app delegate or anything like that? We have this new window group and we set our first screen here. As you can see, we're loading up our content view. And this is going to be our content view with a preview here with the default helloworld. And then taking a look at Netflix, we can see that the first screen we'll start with is going to be our home screen. So we have a lot going on here and we're going to break it down into the smaller elements, just like you're supposed to Swift dry. So you can see we have the bar at the top with buttons to select TV shows, movies in my list. We have this large preview of whatever show Netflix's currently trying to promote at the top, we have some of these scrollable previews that are round. And then we go into sort of a very similar list, basically their categories. And then you can scroll through the movies of those categories. So we have my lives, criminal investigation, a bunch of stuff. We also have some other elements that are unique, like continue watching, which basically shows where you currently are in the show and has a big play button. And then we also get some of these auto playing video cells that auto play the trailer, I believe. And then they also have their own little buttons for playing and adding to my list. So what we're going to start with is building out the model for these scrollable movies here. So we want to just have a list of a bunch of movies on a home screen that are all square and allow you to scroll like this. And then the second thing we'll add is this larger preview and then we'll kinda just go from there. So what we'll do is we'll create a new file and make it a swift UI file, and we'll just call it our home view. So we want to have this and this is something new. Basically, we now have a wire and we have shared, but we also have iOS and Mac OS. So this is because Apple is pushing for developers to build for both iOS and Mac OS. And now with a new Xcode project, you don't create a iOS or Mac OS project, you just create an app. And this allows you to have shared code, iOS specific code, Mac OS specific code. So for this course, everything is going to go into the iOS folders because we are not dealing with macOS or shared in any way everything specific to iOS. So just to keep it clean in case in the future, you want to add Mac OS support. You will already have your project organized where this course is an iOS section and you can have your own code in the macOS. So select iOS creates and we have our home view will enable the preview. And what we can do is we can type. Welcome to Netflix, just so we can have something different here. And you can copy our home view. And if we go into the build Netflix app. And by the way, this file is going to be called whatever your project is with app after it. So my project is called Build Netflix, and this is gonna be called build Netflix app. And capitalization does matter, but this is all set up for you, but just know that yours might be different depending on what you've named the project, but you're just gonna go to the project name app dot swift. And so in our winter group instead of the content, you will actually just load our home view. So now this is going to be our entire application. So if we fire up the simulator, this is all we would see is this welcome to Netflix. And the first thing we're actually going to do is we are going to add a Swift package. So what we're gonna do is go to File. We're going to go to Swift packages, add a package, dependency package we're going to add is called king fisher. So I will have the URL posted under the lesson where basically you can read about what king fisher is and you can see all the information about it and the versions and how to use it and all the documentation. But essentially it allows you to very easily use networking images. So instead of having to build your own implementation of downloading images, showing, showing low wing loading indicators, caching those images from the URL. So you don't have to make network requests every time. All of that is built into king fisher. It's very lightweight, very easy to use. It supports with Package Manager so you don't have to deal with CocoaPods or anything like that integrating into your, into your Xcode project. So very easy, very nice, very clean. You can obviously use any other one that you would like if you have your own preference or something that you know how to use. But for this course I'm going to be showing king fisher. And also if you don't want to use king fisher and your application than any of our king fisher views can just be replaced with a traditional image view that you can be pulling from your own assets. So this is just so we can have a little bit more realistic towards Netflix. Netflix is not saving any of the movie thumbnails into your device. So we will just load them as if we're also doing some real networking. So for the version up to next major is fine. So for me it's just going to be less than 6. So this course should be good as long as you're also less than 6. If you are watching this a little bit later, you may have to do exact. And if you do exact, just do 5.14.1. And then you'll be able to have the exact same version as me to make sure there's no conflicts. But I'll just do up to next major. Click next. It will add our Package Manager. It will download it, I'll check it out from that GitHub. So the GitHub link is the one that I'll have below. And now this is important. King fishers kind of in the middle of a transition. So they're doing this dynamic library, standard library, static library thing. Basically, all you have to do is don't worry about any of the static or dynamic. If you just pick the regular one, which there's two versions, there's king fisher and king fisher Swift UI. And then there's just dynamic and state versions of those. But if you pick either one of these, you will actually use the correct one automatically. So don't worry about choosing between dynamic or static. So we're actually not going be using king fisher it with UI Kit. We're only going to be using Swift UI. This is a 100 percent Swift UI app. So we can uncheck king fisher and just have king fisher Swift you out here. Select Finish, and boom, you'll see something like this. You'll have a little bit of build and loading on Xcode. I'll just take some time depending on your spend on your computer specs. And then you'll see on the left we'll have our Swift package dependencies and we'll have king fisher here. So this will have all of the files 14 fissure. So for our home view, we are going to be showing our lists of movies. So we're going to create a small view where we can pass in a movie. And it's just going to render out a nice thumbnail image of that movie. So we have to do two things. First, we have to define what our movie is. So we're going to have a new swift file. We will call it movie, we'll have it in iOS. And this is going to be our struct, which is going to be a movie. So our movie is going to have a lot of stuff, but we're going to start with the very basics. So we'll have an ID just so it's identifiable, are going to need that for our lists and for Swift UI, this is a good idea for all of your model objects just to have an ID. One thing you can do if you don't want to assign an ID, you can just completely automate this by setting it equal to UUID dot UUID string. So what this does is anytime you initialize a movie struct, you won't even have to set an ID. It will automatically be set to a random UUID string, but you'll always be able to access ID. So we won't do that though for this project. But what we will need is a name. This is going to be a string, and then we'll also have our thumbnail URL. So this is going to be a euro of our image that we're going to use for the thumbnail. So that's really all we need to show our first screen of movies. We're going to add a lot of subsidies struck. For now. This is a very basics, so we'll start from here. So we're going to create a new swift UI view. And we'll just call this our standard home movie. So this is just going to be our standard movies, as you can see on this list, all of these squares, each one is going to be one standard home movie. So when we make a standard home movie, what we need is we're going to pass in a movie into this view. And you'll see why in a minute. But once we do that, our preview is going to complain that we're not passing in a movie and we're going to run into this a lot. Many are reviews are going to want a movie and then they're going to show information based on the details of that movie. And so for our previews, we're going to have to pass in an example movie. So I'm sure what that looks like if we create a movie here you can see we need an ID, a name, and a thumbnail. And anytime we make a view, we're going to need this. And another thing is anytime we modify this movie struct and say we add something new here, we're now going to have to go back to all of our previews and add that new parameter. One thing that we're gonna do is we are going to create a global version of our movies that we can use anywhere and they will automatically update. We just have to change them in one place. So what we're gonna do is we're going to create a new swift file, call it global helpers. And this is not going to be a class or struct, it's just going to be a bunch of static information. They're going to be global variables we can access from anywhere. Some of these are going to be for testing only that you would remove if you're going to be launching into the App Store. And some of these are going to be extension. So sometimes we'll want to have a small extension that will just drop into here because we don't want to have one new folder, one new file for every small to line extension that we add here. But what we'll do is we'll just say let's example movie one. And we will initialize a movie. And for our ID we'll just do that trick that I said UUID dot string. This will give us a randomly generated ID. For the name, will do dark, and for the thumbnail URL would do something a little bit interesting. I have a URL that randomly generates a image every time you access that URL. So for here we want to create a URL with the string initializer. And our string is going to be this URL right here. So it's picked some dot photos forward slash, and this is the actual size of the image. So we'll do 200 by 300. That's fine. Put an exclamation point here because we know this URL is going to work and this is just, for example, movie. So we can force unwrap this. And it basically this is just going to load up a random image. So what that means is your image might be different from my image. But this is enough to have an example movie, which means we go to our standard, I'll movie and this one's a movie. We can actually just say example, movie one. And sometimes it won't auto-completes. But if you go to the file and you do Command S, that will save it. So then, now it should be loading in autocomplete for the rest of the folders. So what this means is remember, now we're passing in this example movie one. If we ever change a parameter, we can just go to global helpers and we can add the primer onetime here. And we could have a 100 different previews and all of them will be using that new information. Now, let's take a look at using king fisher and let's display our image here. So to use king fisher, we first have to import it. And wherever there's king fisher, There's king fisher, Swift UI. We definitely want the swift UI module. And it's actually very, very simple to use. We use this image view and it has a couple options. We are going to choose just a simple URL. It's an optional URL, so you actually don't even have to force unwrap here, but we already know that URL we want to show it's going to be the movie thumbnail URL. So now if you do Command Option P, refresh your preview here. It could take a second to load because it's the first time we're using king fisher and your preview will actually be blank. What you wanna do is play the preview and that will actually fire off the network across by KF image. And you'll see we have an image. Remember that your image might be different from my image. It's randomly generated. And one more thing to keep in mind, king fisher is going to be automatically caching this image. How the caching works is when we've pasted this URL, king fisher assumes that this URL is going to be pointing to the same image always. So what that means is the second time we access this URL. King fisher has already saved that image in a cache, meaning it will not even make a network request, it will just get it from the cache. And so this is really good for working in the preview because it means you won't have to run the preview making that request every time, anytime you use this URL now, you will just load this image from the cash. The other thing to keep in mind is that means that URL will always point to this image now. So the URL is going to be always changing. If you go into a browser and you paste it in, you press Enter, you refresh, you'll get a different image. But since we're caching it, you always get the same one. But yours will most likely be different from mine. So this looks pretty good, but this is looking pretty good because the image is 200 by 300. Our image was a lot larger, like the Netflix preview thumbnails are probably a lot bigger and then they get resized. So we want to add a resizable, and then we want to say scale to fill. So now our image is massive. And what we're going to be doing is we're actually going to be relying on the parent to set the frame. So the standard home movie actually doesn't know how big it's going to be, which is why it's just assuming it's this massive thing. But what we can do is in our preview, this is how we're going to be using the view. We're going to be creating our standard home movie. We're going to be passing in a movie. And then with the parents, which in this case is this preview is the parents is going to be setting our frame. So when we set a frame, we're going to have a width and let's say we want to 100 and then we'll have a height, and we'll say 300. So it's the exact size that the movie actually is from the URL. But basically the parent is going to be in charge of setting the sides, meaning that we'll be able to use this view really in a lot of places in the app. And then we can customize the frame here. So you can also just set the frame here if you'd want to. And now would mean it would be a little bit easier because you would never have to set the frame. You can always just set the standard for movie here. But then now it also mean that if you do set a frame and say a width of 600 and a height of 600. Well, you'll actually see is the image doesn't change. So our standard home movie view will be this big, but our image will only ever get to here. So it'll be less code because you will never have to set the frame, but it'll also be a less flexible view. And we really like flexible views, so we'll do it this way. And that's all we have for our standard home movie for now. So we'll go back to our home view. And now we're going to want to show our movies. So taking a look at Netflix, it looks like the background is a basic black. So we'll start with a z stack, color dot black. And now we have a completely black background. We will add edges ignoring safe area. All. So what this is doing is this is setting this area up here and this area at the bottom to include that view. So the black is not just caught off at this frame here. And now we have some more setup to do. What we're gonna do is we're actually going to create a view model. And the view mode is going to manage more of the logical things we have to do. That's not directly related to actually setting up the views. We don't want our body to get massive with a lot of functions within the struct, doing a bunch of stuff. It would be a lot easier to create a new file, call it a swift file. We'll call it home VM for home ViewModel. Make sure it's an iOS click Create. This is going to be a class on VM. Now remember whenever we make view models, we want them to be observable objects. Make that right off the bat. So what we're going to be having is we are going to publish our movies. Now we're going to be displaying until the home view. And we will call these movies. And these movies are actually going to be a dictionary of strings and then an array of movies. We'll initialize it empty. And the reason we're doing this is because if we take a look at Netflix, we can see that this isn't just a list of movies. This is a list of movies organized By the categories. So we want to know which movies are in my list. We want to know which ones have the criminal investigation TV shows. We want to know which ones are linked to trending now. So the string is going to be our category. And I'll just mark that here so we're not confused later on. So what we'll do is we'll access the initializer here. And we'll run a function called setup movies. So there's going to be a function called set of movies. So this set of movies function will organize all the movies we have into the correct categories. So for now we'll start with one category. So we'll say movies at, Let's say trending. Now, what we can start with, and we will just put our example, movie one in there. So essentially all we have in these movies is just a key trending now and she's going to be an array with just one movie in their example, movie one. So there's going to be one more thing we'll have to do. And we'll actually take a look at the home view before we do it. So in the home view, what we wanna do is want to loop over each of our categories. So we want to have a foreach loop and we want to access all of our categories. And then for each category, here we want to basically have our category. So we want to have category in and within here, we can have a piece of text and just have the category for now. But how do we access this category? So you can actually do that in our ViewModel. So on our view model, we can just have a public variable, call it all categories. And it'll just be an array of strings. Each category has to shrink for now. So we'll open up our codebases. There'll be a computed property. So we'll say return movies, dot keys are going to access all the keys. And we want them to be strings. If we just access the keys, we get not a string, we get this. So we get a dictionary dot keys type. And what we can do is we can actually just map this into a string. So now this is basically just going into our movies dictionary accessing all the keys and mapping them, meaning we're looping over each key. And when we get to that key, that gets assigned into this dollar sign 0. So in here, think of a for-loop is going in here. So for what we're saying here is for each key in the movies dictionary, make sure you take that key, which is a temporary variable here called Tosh 900, and just initialize a string with it. And so basically our output. Of a map is going to be an array because we're looping over our elements here and applying something to each element. What we're applying is we're basically transforming it into a string. So our output is going to be perfect. What we need, it's going to be an array of strings. Now something new and Swift is you actually don't need to put this return. We can actually just say movies dot keys, dot map. Just one less word that we can use. It doesn't matter, but an older version of the Swift, you had to have return newer versions, you don't have to. So now when we go back, what we can actually do here is access our view models, categories, but we don't have the ViewModel yet. So we'll do var VM home ViewModel and we can just initialize it as a home view model. So you don't even need this if you don't want it. You can just say our ViewModel is our home view model. And now we can access v m dot all categories. One thing we do need is we have to identify each category. So we need this ID backslash dot itself. What this is saying is the for-each loop needs to know how it can differentiate between each and every category. So what's the difference between one category and another? And we're telling it that each category is going to be unique and you can just use the hash of each value. So basically, when we have two categories, it will just hash them and then the values will be different. And essentially it will ID each one based on the hash. So now we'll actually be getting our category in the loop. We should be able to refresh our preview. And what we'll see is a square, nothing on it. And our text reason we don't see it is the default text is black and our background is black. So what we can do is on our entire Z stack, if we set a foreground color of white, remember when you apply a modifier to a container, all of the children views get that modifier. Now the child views can also override that modifier. So our texts can have its own foreground color. We can say blue, and now it's blue. But without having any modifier, it will take the default of its parents. So meaning any piece of texts we have in here or anything, well, actually are always have a foreground color of white and less if we specify otherwise. So taking a look at Netflix, we now have the title. So it says trending now. But we want to push it more to the left. So what we'll do is we'll put this into an H stack and on the right of it put a spacer. So now it's all the way to the left. Now what we wanna do is under this, we actually want to have our movies. So we'll take this a1 times h stack, put that into the stack. And under this, we're going to have our movies. So for our movies, it's actually going to be a scroll view. As you can see, we can scroll left to right. So we'll have our scrollview open that up. We're just going to have our horizontal show indicator false. You can see there's no indicator that we're scrolling, which is that bar you get sometimes when you scroll up or down or left to right, we don't want that for Netflix. And if our content, what we want is for now we can just have text placeholder, that's fine. One thing we could do with a scroll view to make it a little bit cleaner is you can actually get rid of content. So if you take this parenthesis, remove it, remove the word content. You can actually close off the parentheses after shows indicators, and it works. Just one more thing you can move from the code. I feel like that will probably be removed as Xcode 12 gets some updates. By default, it probably won't add that content. So this is just a way to make it cleaner right now. Now if we play this, you'll see that the bottom parts actually scrollable and the top part is not because this is a V stack. So only the what's inside the ScrollView will scroll. And this is exactly the functionality that we want. So now let's get to showing the movies in our scroll view, we want an H stack because we want a lot of elements left to right. And in here we want a for-each loop and we want some data and some content. For our content, what we want to get is we want to get the actual movie. Because once we get the movie, then we can have our standard whole movie and pass in that movie. And so remember, this will be a list of the square images, will have to set a frame on this one. Otherwise, I'm going to be massive images. But we have to first figure out where we're getting our movies. So we actually can't just access ViewModel movies because this is a dictionary. We take a look at our home view model. This is a dictionary. This would return a value of string and then an array of movies. But what we can do is we can actually have a, another function here that helps us. We can make it a public function. Basically says get movie for category and we can just say forcats. And what this is going to do is this is basically going to take in a category and it's going to return an array of moving objects. We can just return movies at the category. Otherwise, just return an empty array. So this is very simple. When you call get movies, you give it a string and you'll just get an array of movies. Otherwise it'll be empty. So now we can call this get movie inside of this for each loop, view model, dot get movie. If you're not popping up the autocomplete, go to your ViewModel, hit Save Command S, then go back. Now I'll be able to do ViewModel dot, get movie and see the autocomplete. So we need a category string. Look at that. We're already looping over all of our categories. We have a category string, so we can pass that category in. So let's do Command Option P and see what we have. You can see even if we try again, It's not going to work. Let's read through our error and see what it says. It says referencing initializer on the for each requires that movie conform to identifiable. Very easy to do. Movie you conform to identifiable. So all we have to do is go. Our movie, struct, add a colon conforms to identifiable. And the only requirement of identifiable is that we need an ID and we already have our ID set, so we are identifiable. Now going back into command Option P. And build succeeds. Now, it knows, Swift knows how to use this for each loop, to loop over the movies. And it knows how to identify each movie different from the other movie. So we can hit try again. You can see we have our massive image here. The image is scrollable and we have our training now at the top. So this is where we're going to add our framing. So we're going to add a frame here for each movie. And we'll give it a width of a 100 and a height of 200. So now we have something that looks like this, and we also want to add some padding to it. We'll do some horizontal padding of 20. So you can see that adds a little bit of spacing, so it's not pushed up all the way. And we have multiple of them. I'll also add spacing in-between. Speaking of multiple, Let's actually take a look at why we only have one. Remember a in our view model, we are adding just one example movie to our movies. So let's fix that right now. Let's go into our global helpers and let's actually have something called example movies, which is going to be an array of movies. And in here, we will just put for now our example movie one. But let's just copy paste this and create a bunch of movies. So let's create six movies. So we'll have 2345 and we'll paste this one more time and we'll put six. And so for our movie names, that'll be the only thing we change. Let me just open up Netflix and see what we have here. So let's just look at what's trending. Now we have travelers, we have community, we have a loan, we have Hannibal, we have afterlife. And now instead of just having example movie one will have example movie two, example movies Three. Example movie, for example, movie. An example would be six. So there are ways to automate this and had a little bit nicer. So you have to keep adding male movies. But this is pretty good for just a small number because then we can customize these in any way we want. So now we have this array of movies. For example, movies, you can go to our ViewModel and we can just say, instead of an array of movies, we already have an array which is our example movies. So now our training now is going to have all six movies. We go back to our home view and varchar preview. It will load for a second and we have six movies here. You can see that all the same image. So that doesn't look that great. So let's actually fix that. We can go to the global helpers. And one easy thing is you just have to change the URL anyway. So if we actually add a backslash on this one, that'll be a totally different image. If I make this 3 0, 1, 3 0, 2, 3 0, 3, 0, 4, we're not really going to notice one or two pixels here because we're scaling it anyways. But when we go back, you can see that they're all going to be different URLs. And the only reason that was even causing the images to be the same is because we're caching them. So now we wanna do is we want to see what multiple categories look like. Remember we're accessing are all categories. If we command control into all categories, you can see that we're actually accessing this movies. So if we create a, another category like stand up comedy, we can see what it looks like with multiple. We'll put in the same example movies. We'll just say dot shuffled. So basically they'll just be in a different order. So kinda looks a little bit different instead of being the same on top of each other. So we have these but they are on top of each other. The reason on top of each other is because of this outer for each loop. Let's think about what this is doing. We have a foreach loop for every category. We're going to render everything here. This is basically a V stack. So we render our first stack. We place it on the screen. Now are for each goes to our second category of rendering a second V stack and we place it on the screen, but which container are these V stacks in there, not in a foreach loop before each just renders things. This V stack is actually inside this z stack. So essentially it looks like this. We'll have 1 v stack and then we'll have another stack. So that's what this forEach is doing. We have two categories, TUV stacks inside a z stack. So you can do the first one is going to be behind just like our color, and then the next one on top. So what will actually do is we will wrap this foreach loop into its own v stack. And this is going to be our main stack. Okay? So we'll put main of V stack here because everything rendered here is going to be in one V stack on top of each other. If we take a look at the Netflix app, we're going to have a big preview at the top will have a row of previews. We'll have our different elements here, and then we'll switch up the two kinds of elements. But everything is going to be on top of each other. So we'll have the menu bar at the top. That'll be in a V stack under that will be this big preview, under that will be this custom row of previews. And under that we'll be starting off this big block of the different videos. So we want all of that in our main V stack, which is going to be here. So we have our category and you can scroll left and right on this Netflix. Remember we are getting our home movies with networking requests with king fisher. So when you have, let's say 50 of these, then as soon as this home view loads, it's going to make the networking requests for all 50 categories and say we have ten movies in each category, that's 500 movies. So we start just firing off network requests for 500 images. Instead of doing That's one thing with the new Swift UI to 10, we could just add lazy. So now what we're doing is we're basically only rendering the views that are going to be on the screen. So think of this as similar to reusing views in a TableView. So when you load a TableView, if it has a 1000 cells, you're not loading a 1000 cells, you load the 10 or 20 that are on the screen, plus one or two at the bottom so that you can have smooth scrolling. And as the user scrolls, then you are initializing, making the request and loading all the data, essentially right before the user needs it. All you have to do is add this one lazy to the frontier V snack and we're doing that. Another thing you could do is technically right now when we load one categories a trending now, we instantly fire off the requests for all of the movies. That's because of this H stack here. Each of our movies is inside here. You can also add lazy a2 RH stack, meaning that like this image, this blue image here might not fire off a request. Because as the user scrolls up and down through 50 categories, maybe they don't even see this image for the majority of them. So there's no point in doing it. But as soon as the user interacts with this, then maybe we start loading this image here. And remember this is all done behind the scene. Just like TableViews, you're not exactly selecting when they get reused. It's up to the system itself. So we don't know maybe that image is being loaded, but maybe we're waiting on the next one to be loaded. So this one here. So this is kinda personal preference depending on your app. If you want to load the whole category at once, just remove the lazy. If you want a little bit more performant, I guess it depends on how many elements you have. You can just add late here. Now one thing to notice is we can't scroll up and down. So we should be able to have content up here, content down here, and scroll up and down. But right now we can't. The reason is because our main V sac is actually not inside of a ScrollView. All we have to do is embed in a V stack. And you do that just because it automatically adds the curly braces. So you can see we have a curly brace for our V stack, and I can change this V stack until scroll you very easily. So now automatically our content got pushed to the top, and now we can scroll up and down. We can scroll left to right with no problems. Now one thing we wanna do is we do want to open this up and say shows indicators false. This will just mean that as we scroll up now we're not going to have that bar on the right with loading and loading indicators with the scrolling indicators. Let's just do one last thing for this video, which is just our text a little bit. We want the text to look a little bit more like it is on efflux. So for now we just have a piece of text, whatever the default is. But let's just give it a font of, let's say Title 3. So that's pretty decent and now we make it bold. And so that right there looks pretty close to what we have on Netflix. Obviously, we can change the font to be exact, but for now this is pretty close. So we're going to have a little bit of a better idea of what this looks like by going into our home view and actually adding a couple more categories here. What do the same thing, just have our same example movies, but shuffled them around. So we have trending now, stand up comedy. We'll do watch it again, and we'll do sci-fi movies. We go back and refresh our preview. You can see we have a bunch of movies. It's the same six images just shuffled around, some of them being the same position. But now we can scroll up and down through all of these. We can scroll left to right with no problem. So we'll start this lesson here. The main takeaways from this is how lazy V stacks are like reusing cells for TableViews. So you want to use this when you don't want to load all the content until the user gets to it. Very good if you have thousands of cells or if the views that you are rendering our heavy. So they are videos or they are images, or they are loading and doing a lot of complex data. You don't want to do that 500 times, a 100 times. You want to wait until the user needs it so you can just add lazy. And the second takeaway is that we want to keep our body of our views as simple as possible. So whenever we can, if we can have this functionality like accessing all categories, if we can put that into a view model. So we can have all of our logic here. If we want to get movies by different category, you don't want to be filtering and doing all kinds of stuff in your for-each loops. You don't want to be having all kinds of functions. You can add functions here, but you want to rarely do that. And a lot of times I like to only have functions for a 100 percent UI specific things. So if we're calculating some sort of animation, a ViewModel doesn't really care about animations. But if we're trying to choose which categories to show, that's a kind of logic that we can have a ViewModel do. Because maybe this is based on user preferences. Maybe we're using machine learning to show the categories in a specific order. So maybe we're, we're now sorting this in a specific way based on some information we've collected on the user on what they do like to watch, which is probably something Netflix does do so that if you're into sci-fi movies, you'll see sci-fi at the top. All of that logic does not belong in the view. All that logic should be offloaded to the ViewModel. And so with something like this, what we've done is we can now organize this all categories variable in any way we want, right? We can throw other functions in here. We can have, this can be a 100 lines long of just a bunch of custom different ways of super specific ways to organize these. And we will have to change our view at all. The view doesn't care. The view just accesses this variable, identifies them as long as there are string, everything works perfectly. Another thing to keep in mind is if you're ever gets stuck, just tap resume tab, Try again like 34 times because it's pretty common for it to not break, but take a couple tries to kind of get in the loop of working correctly. Specifically, this is also a beta Xcode. 4. Large Movie Preview Part 1: And we'll come back to the course. So let's take a look at what we have so far, and then let's compare it to what we have on Netflix. So you can see on Netflix, we have this large preview at the top. We have this previews scroll. And then we start with our normal square movies. And so what we have so far is we've built out our square movies. So we have a model for each movie. Take a look at that here. So far we have the ID, name, and thumbnail. We have a ViewModel where we're organizing our movie objects into arrays of movies organized by their category. And you can see the string is the category name. We can also have some helper functions here to make our view a little bit easier to work with. And then we set up just a couple of sections here to have something to look at. So taking a look at our view, we can scroll through these sections. I believe it's six movies that we have just randomly shuffled. And we can scroll up and down because of this scroll view here. And we can also scroll left to right because of this second scroll view here. So we have a vertical scroll view and then we have a foreach loop. And then for each category we have a horizontal scroll view. So the bottom part, when you scroll down to about here, this is looking pretty similar. And what we're gonna do is we're gonna build out this top section. So we have this, what I'll call a large preview. And it has three buttons here you can add to your list, you can play it, and you can get more info. So we haven't built out any details screens. So doing info, we haven't built this screen yet. But what we will do is just build out this preview. So we have a large image at the top. We have a little bit of text. So it says dystopian exciting suspense for so these are categories. And then we have three buttons. So what we'll do is we will make a new file. It's going to be a swift UI file, and we will call it the top movie preview. So there's going to be our preview at the very top of our screen. So this is what we'll call it for now. And we already know that the basic organization that we're doing in this course for a lot of users were essentially passing in a movie. So we want to make a reusable view that we can pass in any movie object we want. And from that, it will render out a large preview for us. Obviously right off the bat, we're missing our parameter. We can fix it and you can pass in an example movie. So it doesn't really matter which one we could do one. And we can refresh our preview and it'll just say helloworld. So one thing to keep in mind is the text you see that says n series, another life. I'm going to assume that this is part of the image that Netflix is uploading. So I don't think they're actually rendering a custom font on top of the image. So basically we have three parts stacked on top of each other. We have this image right under that. I guess we're going to have an H stack of our categories, and then under that will have an H stack of our three buttons. So when you're building a swift UI, that's one of the ways you want to approach making a view is you want to just right off the bat, start training your mind to see everything in H stacks and stacks. So this is going to be an outer layer of the stack. With two H stacks for the bottom elements. So let's make our outer V stack. And we know that we're going to have an image and we're going to load this one from the web just like all our other images. So we want to king fisher Swift UI, and we will just get our image. We're going to have a URL. We already know that our movie has a thumbnail URL. So there we go. And almost anytime we're working with images, we're going to add resizable. And for this effect we're going to scale to fill. Now we're also going to add clips just to make sure that it's clipped on the edges so that it doesn't stretch out past its frame. This is pretty common for a lot of the images I use is I add resizable scale to fill and clipped just to keep my images nice and clean. And I actually notice that the text is on top of the image. So as you can see, it's not that the text is just underneath the image, the text, the dystopian and exciting, suspenseful categories are actually on top. And it actually looks like this h stack of buttons here with my list and the play and the info is also on top. So I think they're adding a gradient to this image. And I think this is actually just one single view with the background being an image. And then towards the bottom, we have these two stacks with the categories and with the buttons. And then there's background has this dark black gradient on it. So you can see if we have our text down here with categories, it'll always be underneath the image. We actually want this text on top of the image. So we're going to change this V stack into a z stack. And now we have our categories on top of the image right in the middle. So we know that under our text is going to be our buttons. So we can place this categories into a V stack. And then we can just put another piece of text for now and just say row of buttons. So this is going to be our shrinks for the categories. This is going to be our row of buttons right in the middle, because everything is centered by default. But what we can do is use our nifty space are here and just push everything down. So now this is pretty close to what we have for the Netflix UI, where we have the image. And then at the very bottom we'll have our row of categories and our row buttons. And one thing we'll do for a lot of these Netflix queues is just add a foreground color of white. Make sure all our text and buttons and everything by default is going to go to white, because really everything is white on a black background for this app. So now we need these categories, which means we have to update our model. So our model object has to have these categories so that we can display them. So I'll add a level of spacing here and add categories. And it's going to be an array of strings. So you can have as many categories as you want. Now, since we've added these categories, that means that when we go to our global helpers, we will get an error here if we try to build, because we don't have our categories added. So we can do is try to build and then select all these and do Command, Option Control, F. So Command Option control efforts, the bottom three buttons next to your Spacebar and then F. And basically that fixes everything. So that's why it's f. So this can be used only when the fix, it pops up like so. And it has a fixed button. Essentially this just automatically clicks that fixed button for everything you have selected. So you can even do this for an entire file by doing Command a, which selects everything, and then doing Command Option Control F. So that will also fix everything for the whole file. So what we'll do is we'll just copy the same list of categories you have. Dystopian, exciting, suspenseful, and sci-fi. Sci-fi TV. Sci-fi TV. So we'll just copy this row and just have the same categories for all of our movies for now. So this is why I had this big list of global movies, because we only have to make this change six times here for these movies, but they're in one location because we don't have to have this example movie one be updated and then this preview be updated as well. And as we add more and more views, it'll just become more of a headache to keep updating all of these previews. But now this is already pointing to example movie one, which from the global helpers already has the new information. So it's a really, really easy way to build out the previews is just having global sample data. So now instead of our texts will actually be able to shore categories here. So what we wanna do is instead of texts will erase that. And we're going to have an H stack because we know our text is going to be next to each other. It's going to be four categories for this movie. Dystopian, exciting, suspenseful in sci-fi TV. And so we want a foreach loop here. And the data that we're looping over is going to be our movie objects categories. And then for our content, we want to have our category. So that's going to be a string. And so this is a string. We have the idea and this is really easy. You could just add this backslash dot self in our foreach loop, we'll just put a piece of texts with our category. So at the bottom here you see dystopian, exciting, suspenseful sci-fi TV with white text, just like how it looks on Netflix, looking good there. If we notice on the Netflix app, there's actually this dot next to each category. So it says dystopian and then there's a little circle. So it's making this circle. We're just going to use a system image. We can just put our text into an H stack. And we can add that with a image and we'll have a system name and it's going to be a circle dot fill. So that's our circle there. And we can make it foreground color blue. And then we can also just give it a fought. And we can do a system size so we can pick with a CGFloat any size you want. And it's really, really small, so we'll do three. And it's kinda hard to tell on this image. Let me zoom in because it's blue for the image. So your image might be easier to see depending on what your URL has posted for you. But basically you can see to the right of dystopian, we have a little blue circle and then we have our circles there. One last thing we'll fix for this lesson is if we look, we can see that to the right of dystopian is a circle. Exciting has a circle, suspenseful has a circle, but the right of sci-fi TV does not have the circle. So it's, the last element does not have a circle to the right. But we're using a basic H stack where for every single category to the right of it we have an image. And so if we zoom in and we can see that to the right of our sci-fi TV. We will have that circle. Really hard to see with this image. But right there you can see we have that circle to the right of sci-fi TV, and we don't want that. So what we'll do to remedy this is we want to check and see if our category is the last category. So what we wanna do is we want to create a check somewhere. We somehow want to know when this foreach loop gets to the last category. Because if it's the first category, we are on a circle. If it's in the middle somewhere we want to circle. But if it's the last category, we don't want the circle to the right here. We're only getting string, the category. We have no idea if it's the first or last. And one hack way to do it is we could just assume that there's always four categories. So we could just have it be for the first three, we add the circle and for the fourth we don't. But we will just actually build this a little bit better. So you can have one category or two or three, and it will always have the circles in-between categories, but never for the last one. We'll do is we'll go outside of our body and make a function where we can check if our category is the last category. And we'll just call it is category last, where you pass in a category which is a string. And we'll actually return a Boolean here. And basically what we wanna do is we want to count how many categories we currently have. So we'll have a count and we can get that from our movies, dot categories, dot count. So this is how many categories we have in total for this movie. So in this case, this will be a number. For. Now what we wanna do is we want to figure out where this category is in the array of movies. So what index do we have? Is this index 0? So it's the first one in this array, or is it index four? So it's the fifth element. What we're gonna do is we're going to compare that index to how many we have and totals or a category count. Our category count is two. And then the category that we're passing in, let's say dystopian would give us an index of 0, then we know that it's not the last one and we can return false. I know that looking through an array for a certain object gives us an optional, and it gives us an optional index because that array might not contain the elements. So if we use this function and call for category 1111111 as a string, that's not going to be found. So we'll actually get nail for this index. So what we'll do is we'll say movie dot categories dot first index of. And you can see if we pass in our string, which is our category, we can just open our curly braces. And now this is the index. We have a category, we'll get the index. And now we want to add one to the index because our count is going to start 12345, but the index is starting with 0, so 01234. So we want to up our index by one, and as long as it's not equal to the category count, then we know we can return false. And then down here we have to return something, so we'll return true. So what's happening here is let's go through it. So we have dystopian is gonna go into this function. The category is going to be dystopian. The category account is going to be our categories dot count. In this case, it's going to be four. So this is now four. Now, if we have an index which is our categories first index of dystopian. So the looping over every element in our categories, the first time we get to a category that matches this string will get that index. And of course we'll hit index 0 and find that dystopian matches the dystopian. And so now we have index as 0. And then we're saying if index plus 1 is not equal to the category account. So if this is saying if 0 plus 1 is not equal to four, then we return false. So 0 plus 1 is not equal to four, so we return false because it's not the last category. So dystopian will not be last category. And for sci-fi TV, the same thing will happen, but it will be 3 plus 1 is not equal to four. So if three plus one is equal to 4, return false, but it is equal to 4. So our sci-fi TV is going to have an index of three. So we'll go down here and we'll return true. So now we can do with this function is we can say is category last and put it down here. And we have an H stack, and we have our text, and we have our image will put down here if our category is last and we need a string, we have our string right here. And we actually want to check if it's not the last one. So we'll reverse that Boolean. And if it's not the last one, then we'll move our image into here. So now you'll see if we resume the preview, we can zoom in. And to the right of dystopian. We have a dot to the right of exciting. We have a dot suspense, we have a dot next to sci-fi TV, there is no dot. So what we're doing here is we're basically checking if it's the last category. Just don't put this dot. And basically this is an optional view, so it will just have nothing. You can also put an else here and you can also have something like last. So you can have a conditional saying if this Boolean is true, show this view, otherwise, show this view. And you can also stack multiple like so. So you can have a whole chain of if else, if else, else inside of your body. And as you can see now when we hit that else, we just have the last view, which is a piece of text. So we don't want this because we just want an empty view. So we just wanted nothing rendered them. And I mentioned this before that a lot of the functionality I like to delegate to a view model and less if it is specifically to the view. And this is something that I think you can either put in a view model. You can return if a category is last or not, or you can keep it in the view. For simplicity sake for now, since this is the only functionality that we would have in a ViewModel, I think it would just add more complexity to create a view model. Just have one function, have that as an observable object, right? All of that out here. Because then if another developer or you after a couple months, I can tie your project. You're looking here, it will have view model.py is category. You would have to go and check out what that view model is, what it's doing. And it just has one function. So in this case, it is somewhat related to the view. And since it's the only thing that we will have here, I think it's totally fine to have it outside the body and it doesn't add too much complexity to our view. But definitely inside the body, we don't want a ton of checks like this. So we want to just have something clean like if it's not the last category, then we can show our image. So we'll end the lesson here. And in the next lesson we'll get started by building our row of buttons. 5. Large Movie Preview Part 2: Okay, Welcome to part 2 of building out our top movie preview. So for a very brief overview of what we set up in part 1, we have a z stack, meaning where a staggering elements on top of each other. We took this image and on top of that image, we stacked an entire stack. You can see the frame here on the right. It's actually on top of our image all the way to the bottom. But then what we did was we added this spacer so that actually pushed everything down as low as it could down to here. And then in there we have an H stack, which is our category row here. So we're looping over our categories and we have a piece of text with a category. And then as long as it's not the last category, we put a little blue circle to the right of it. And then under that we just have a piece of text saying a row of buttons checking out Netflix will see that we should have actually a row of buttons with my list play and info. And one small thing we'll do is for this text, we will actually change the font, make it a little bit smaller. It will actually do footnote. You can see that in the Netflix app it's actually pretty small. So the footnote font is little bit closer to what it is in the app. It looks very small in the preview, and it looks especially small compared to this massive image. But you'll see once we actually place our top when we preview and we give it a frame once its parent will assign a frame to it, which it's going to be the home view. So the home view is going to assign a frame to this Preview. And then our image will scale down a lot and the text will look a lot nicer next to it. So for this row of buttons, we can start building it out with an H stack. We know that it's going to be multiple elements left to right. And we know that it's going to be a button, but we'll just do a piece of text for now. And we'll just say my list and then we'll copy this three times. So we have my list and then we have a Play button, and then we have our info button. So we'll just say Info button. So my list Play button, info button. So taking a look at the Netflix app, we can see that as we add it to our list, it's actually changing. So the check-mark changes into a plus, has a little bit of an animation to it, and then the info button has no animation. And what I want you to notice is the similarities between these two. They're both a image, basically a system image, and then under that a piece of text with the same font and the same stylings. So I don't really want to make a view here and then add like an animation and add a transition and then go down here and have another button, a different view that just doesn't have that functionality, but then it's going to have a similar style to this one. Because I already know that if we click on this info tab, one thing to notice is that we have another Majlis button, and now we have a rate button. And the right button is similar because as we'd thumb something up, it basically changes. And as we thumb down, the image changes. So we have some different image options, but the way it looks is exactly the same. So it's a system image on top of a certain size. And then a piece of text underneath. And so we want to build out a view that's reusable, that we can put both on this screen and we can use for transitions and animations. And we can also have on the info screen without having to build seven or eight or nine different views and just have them all here. So we're going to create a new swift UI view. And we're going to call it a small vertical button. And so we will refresh our preview. And this small vertical button we know is going to take some information. So it's going to have a piece of text. This is our text at the bottom. So this is what it's going to say underneath. So we'll just take a look at that mylist button for now. So it's going to say my list. We also want a on image and an off image. So you can see when my list is on or enabled, however you want to think about it. It has a check mark. And if it's an off state, we have a plus. So it's two different images with an animation. And I want to be able to just pass in these images to this view and have it render it out however I need. So what we'll do is we'll have, is on image that's going to be a string. We're going to be using the system images. And we'll do the same thing for is off. So having these be strings means that we'll be able to do something like this. Have an image with our system name and then we'll pass in that is on image. And then another thing is we need to know if it's on or not. So are we showing and B is on image or the image, and we'll use that with a Boolean is on. Now we're going to be missing all of that from our preview, you want to click the fix. And what we'll do is we'll recreate the mylist button. So we'll say my list for the is on image. It's going to be called checkmark and the is off image is going to be called Plus. And we'll just say it is on. So refreshing this, nothing will change because we just have our piece of text, but we're passing in a list, a checkmark, and we can organize it like this are on image and our IFA off image. And we know which one to show whether the on or off. So now let's start building this out. We know this is going to be a button. So we'll have this action label will open up the action. We don't know what I'll put here. This is just gonna be our action. And we can just put whatever view we want in the label. So if we put a piece of text here, then it'll be a piece of text for our label, we know that it's going to be an image on top of a piece of text. So think of everything in Ajax and v stacks. This is going to be a V stack. So we'll have an image with a system name. For the system name, we will use them. So I don't know if we should use the on or off because it's dependent on whether this Boolean is on or off. So let me show you a bad way of doing this, which is what we did before. We just have an if statement inside our body. So remember what I said before. We want our body to be as simple as possible. If we have any calculations that need to be made, we wanna do them either in a function outside of our body or if it's very complex. And we have a lot of functions. We want to have a view model that just manages the state. So let me show you what happens if we don't do that. So let's say we want to just check here and we say, well, if is on. Then what we wanna do is have an image with the A's on image name, right? So is on image space this out. And then we can obviously just say otherwise, show the image with our system name is off image. And now here's a problem because I want to add some modifiers to these images. So let's just say I want to have the foreground color to be white, first of all. So we'll have a foreground color of white. And now you can see that since it's on, it shows white. But if you pass in false for our preview, then it does go to the plus correctly, but it's blue because now we have to add this foreground color down to here. And now look how large and complex this is. If we add four or five or six different modifiers to each one, look at how many lines of code we have, just to have one image, we actually are duplicating everything. Later on. Maybe we have three states. Maybe it's not just going to be is on. Maybe we will have some sort of state is on, is off or waiting and loading. So maybe we have four states. So what you're going to have four large if else with repeating all of the modifiers. And it's going to get very complex, very fast for no reason or actually do is just completely get rid of this. And what we wanna do is we want to have an image with a system name and we want to get the correct system name. So we can either create a function or you just have a computed variable. And I'll just show you a computed variable, since we already did a function outside of a body. So we'll just take a look at it, a computer variable and we'll just call it image name. So this is just going to be not that is on image or the ISAF, but the correct image name. And this is going to be a string into computed property. So we will have a, something like return. And if we do return is on image, this will always just return this string up here. So now we can use that image name. Refresh our preview. Everything should work. Hit try again a couple of times until it does work. And we have our blue check mark. But you can see if we change this on to true or false. It doesn't matter because we're always just returning the on image. But we can have our if statements here. So if is on, then we're going to return that is on image. Otherwise, we will just return the orphanage. Now you can see if we change this to false, we get r is off image, and when this is true, we get the image. And so as you can see, what we've done is we've taken the complexity out of the view and we've brought it out into either a computed variable or a function outside the body, or a wicked put it into a view model, but we don't want to in the body and that makes it a lot cleaner because now we can just have one set of modifiers here. And reading this is lot easier. Now we have our image. We want to change the foreground color because we know the image is going to be white. But once we change the foreground color to white, a problem that comes up is we can't see it in our preview, but you can actually use this preview anyway you want, if you notice. Our body, Here's just a body returning some view. And our previews actually just a preview returning some view. We don't actually have to just return the exact struct that we're previewing. So we can actually just wrap this into a V stack, change the v stack into a z stack, and then we can just put the color black behind the vertical button. Now, we can actually even make the edges ignore all. So we can do anything we want in this preview and customize it any way we want. And the view is actually just totally optional. We can just preview a black screen. We don't even have to have the struct here. This struct has actually created for you in the preview as a convenience so that you don't have to write out the static var preview some view and then set up your struct. But you can actually just customize this any way you want. What we wanna do is we want to add our piece of text. So we'll have texts. Texts. Remember we're passing in a string here and you can see we have my list and that's where we're passing in. Perfect. And we want to change the foreground color to be white. Perfect will change the font to be a system size 14. It's pretty small for these buttons. Perfect. And then we, we'll bold it. Then we will change the font to a system size 14, and then we'll bold it. So it's a pretty small text, but it looks pretty close to what we have on our Netflix. Now, one more thing is we hav