[MUSIC]                         
Stanford University.            
>> All right, well,             
welcome to Lecture 5 then of    
CS193P this Fall of 2017.       
So I'm gonna take just a few    
minutes of the beginning here   
to go over just a couple of     
more little Swift things.       
These are actually in your      
reading assignment for          
this week. So I'm really        
just kinda emphasizing these    
things, then we're gonna dive   
into our main topic today       
which is views, drawings, how   
you do custom drawing in iOS.   
And I'm gonna start with a      
huge demo, the only thing I'm   
gonna probably be able to do    
today is the model of our MVC.  
But that's gonna allow me to    
show you an example of enum,    
which we didn't get to          
work into concentration.        
So you only theoretically know  
enum, and we'll be actually do  
enum. All right, so let's do    
these little minor things.      
One of them is error            
handling in Swift.              
Now, a lot of times             
you'll have an error and        
it will be something that       
kind of, could be expected or   
anticipated. You know, you do   
something over the network and  
there might be                  
a network time out,             
that's kind of a normal error.  
If you have that kind of        
error, you likely would have    
an argument to                  
the function that goes and      
does that network call. Maybe   
it's even a closure that calls  
you back and said, I found      
this somewhat expected error.   
But sometimes you have errors   
that you don't expect or        
that are kind of rare, and      
really disrupt the usage of     
a method or whatever.           
And in that kind of error,      
instead of having to have one   
of your arguments be an error   
handler or returning an error,  
or something like that.         
You can do something that's     
called throwing an error.       
Now, in other languages,        
you might think of this as      
like raising exceptions or      
something like that.            
It's a little simpler and       
more elegant when you design    
in Swift. It's as simple as     
this, a method that could       
get an error, okay,             
a significant error that would  
disrupt what it's doing,        
can decide that it throws       
errors. And you see these       
methods very clearly because    
when they're declared, they'll  
have the word throws at         
the end. So this function save  
throws. Okay, if it gets an     
error, it throws this error.    
Now, when it throws an error    
at you, you need to catch it.   
Okay, and                       
you catch this error and        
then you can look at it and     
decide what to do. So           
how do you catch an error       
that has thrown? Well,          
you do that by putting this do  
catch construct around your     
call to the method that might   
throw. And you say, try, in     
front of the call. So you're    
going to try this method        
that it might throw. But since  
you've put it inside this do,   
catch thing, that thing you     
see up there, you're going to   
catch that error. Okay, so      
it's as simple as that.         
So, any method that throws      
has to be called with try.      
Okay, you have to let Swift     
know I understand that this     
can throw, and so               
I'm trying it.                  
But it doesn't necessarily      
have to be kept, caught,        
and I'll show you in a second   
how to do it without catching.  
If you do wanna catch,          
then you do this do catch, and  
in the catch you notice         
there's the green, let error.   
Okay, that little error thing,  
it's just a local variable.     
That's the thing that           
gets thrown at you, okay,       
when it throws an error.        
And it's going to be            
something that implements       
the protocol error, but         
there's actually nothing        
in that protocol.               
It just identifies, it's just   
typing this thing as error.     
Now, in iOS when things,        
errors gets thrown at you,      
there almost always             
going to be NSErrors.           
So an NSError is just a class,  
it implements the Error         
protocol which is to say that,  
that nothing in particular.     
But NSError has a lot of        
nice methods and vars,          
like the error code, even       
a localized description of      
the error that you could        
present to a user,              
for example. So the way this    
goes is if you had a function   
save that throws,               
you're gonna go looking         
in its documentation and        
see what kind of NSError stuff  
it can throw. And it'll throw   
certain errors like save,       
the save maybe it's for         
saving into a database and the  
disk is full, so the database   
couldn't save so maybe          
there's an error code for       
disk full or whatever. So this  
is what you do if you want to   
catch a thrown error and        
kind of handle it, look at it,  
see what it is, decide what     
to do. But you can just say,    
try!, and what that means is,   
try this and                    
if it throws crash my app.      
Now,                            
you would only do this if       
you were 100% certain that,     
that thing could not throw in   
the circumstance that you're    
doing, which is extremely       
rare, so we rarely do try!.     
But a better one if you don't   
care about the error is try?.   
So try?, means please try this  
and if it throws, don't crash,  
but just ignore the fact        
that it threw. So               
this is kind of like try and    
ignore. Now the interesting     
thing is, you might be calling  
a function that returns a       
value. An int that can throw.   
So here I've got my error       
prone function that returns     
an int, okay, and so what if I  
wanna try it with try?. Well,   
if it succeeds, I need that     
int back. But if it fails,      
I can't get the int back. So    
what happens when you do try?,  
it changes the return value     
essentially, of the function    
to be an optional version       
of that value. So               
if you have an error prone      
function returns an int and     
you try? it, and you let it     
equal something, you know,      
let x equal that. This x now    
becomes an optional int,        
because if it throws,           
it's gonna give you             
nil. If it doesn't throw,       
you'll get the normal x value   
that error prone function that  
returns an int, returns. Okay?  
So that's error handling.       
There's not a lot of methods    
that throw in iOS there, in     
there occasionally. You know,   
you might have a typical app,   
maybe you have three or         
four of them, somewhere.        
They're fairly rare but         
you got to know how to handle   
them. So these are the ways to  
handle them. All right, I       
wanna circle back now to Any.   
This type Any that we saw with  
NSAttributedString dictionary.  
There's another one called any  
object which is exact the same  
as Any, it's just for classes   
only, and the object is         
the any of classes only. And    
I told you that Any means, you  
don't know what type it is,     
it could be any type. And       
we also know that that's not    
very Swifty, and cuz Swift is   
strongly tight. So Any and      
AnyObject are in there for      
compatible with Objective-C.    
Objective-C had a very          
important type called ID which  
was essentially any and it was  
built in to all of the APIs.    
So when Swift came along and    
tried to be strongly typed,     
it had to have this             
one concession. So              
we don't use as I've said,      
any in our own code, it's for   
backwards compatibility.        
So variables of type any could  
hold any type. Structs,         
enums, classes, anything.       
And the problem though is,      
you can't send any messages to  
something of type Any, because  
you don't, in your code,        
know what it is. Okay?          
Now, Swift, under the covers,   
might know what it is, but      
since you've typed it Any,      
it's assuming you don't want    
to send any messages to it      
that you don't know what        
it is. So, how do we            
deal with that case in Swift    
where we got the strongly type  
language, we can't send         
a message to Any. Well,         
we got to convert it. Now,      
let's talk about where you're   
gonna see it, you already saw   
it in NSAttributedString case,  
right? Well,                    
we have that dictionary.        
Another place you will see it   
is arguments to methods. So     
here is a method                
called prepare for              
segue. It's a UIView            
controller method, right?       
You all know what               
a UIView controller is?         
We made one for                 
concentration. And              
I talked about when we do MVCs  
and we have multiple MVCs, and  
they own a whole screen. Well,  
we sometimes transition from    
one MVC together, to another.   
And this prepare for segue,     
a segue is a transition from    
one MVC to the other, this      
gets called in a view control   
when transition happens. Well,  
one of the arguments to it      
there at the end is sender of   
type Any?. Okay, an optional    
Any. And that's basically       
what button cause this MVC      
transfer to a new MVC so.       
So it could well be a button    
that, that sender is but        
it can also happen if you       
click on a row in a table       
view. So that's not a button,   
that's a table view. Cell,      
okay, or it could happen        
from something else.            
It could even happen by code,   
in which case this is a nil.    
So that's why you need Any      
right there, because you're     
not sure whether it was a       
button or a table you cell or   
something else that caused      
this thing to happen. So        
you'll see it as arguments, a   
case very rarely to a function  
like this where you can kinda   
pass anything in there,. But    
how are we gonna use this       
Any stuff? Okay, let's say      
a button was passed on your     
table, how do I know what it    
is and talk to it, and all      
that when it's this Any thing.  
Okay, before I show you how to  
do it, of course don't use Any  
in this course except for to    
do backwards compatible call    
APIs. You don't have your own   
data structures would not be    
use Any. Some people            
try to use Any when             
they basically don't know how   
to design a data structure,     
and they're like,               
I'll just make this an Any,     
an array of Any and             
I'll just start throwing        
random things in there.         
No, we don't do that, okay,     
that's not, Swift. All right,   
so now how do I use Any.        
I have to convert it to a type  
that I do know, since I can't   
send any messages or vars,      
I have to convert it.           
And we convert it,              
with a special keyword and      
Swift called as,                
as question mark. And what      
as does, is it just tries to    
convert that any to the type    
you specify and if it can't,    
it returns a nil. That's        
why it's as question mark.      
And it's as simple as that.     
So here's an example,           
it's best learn                 
by example here.                
Let's say, I have a var called  
unknown, which of type Any, so  
I don't know what's Any.        
It could be anything in there,  
and I think that that thing     
in unknown might be of type,    
MyType. I'm not sure but I      
think it might be might type.   
So I'm gonna say if I can let   
foo, which is a new variable,   
equal unknown as MyType.        
Then inside there,              
I can send messages to foo      
that MyType understands,        
right? So I've just             
converted unknown into          
a new variable of type MyType,  
if possible by using as.        
And you can see this is nice,   
it reads like English.          
If I can let foo equal          
unknown as MyType,              
then I'm going to use it        
as MyType. So that's it,        
it's very simple,               
that's how we access Any. And   
if it wasn't, if unknown        
was of some other type and      
couldn't be                     
interpreted as MyType,          
then this the curly braces,     
that stuff doesn't happen.      
You could even say else,        
and something else, and         
something else would happen,    
that would be fine too.         
Now this casting of             
As is not just for              
Any, we can also cast other     
things. Why, why else would we  
ever want to cast? Well one     
classic one to cast, is to      
cast from the variable type     
to one of its subclasses. So    
let's look an example of that.  
So here I have a variable vc,   
very importantly it's of        
type UIViewController.          
In other words the iOS class,   
UIViewController that's         
the type of vc. Now I'm         
setting it equal to creating    
a ConcentrationViewController,  
which is a subclass, let's      
say, of UIViewController.       
Now the type vc,                
even though I assign to it      
a ConcentrationViewController,  
that type is still              
UIViewController not            
ConcentrationViewController.    
That's not its type,            
its type is UIViewController.   
But this is a legal statement,  
because of course               
a ConcentrationViewController   
inherits from                   
UIViewController, and that is   
a UIViewController. Now if      
I wanted to send flipCard,      
lets say that was a method in   
ConcentrationViewController,    
to vc I could not do that. It   
would not even compile, why?    
Because vc is subtype           
UIViewController, and           
the class UIViewController      
doesn't have flipCard.          
ConcentrationViewController     
has it, but                     
not UIViewController.           
So people get confused about    
this, it's kind of like back    
when we're talking about        
the protocols and               
I had things to move.           
And it was of type movable,     
and I had a car in there and    
I want it to send a change oil  
and people were like, why not?  
Well, because the variable was  
typed to be a movable, and      
movables didn't know how        
to change oil, cars do.         
This is the same kind of thing  
here, exactly the same thing    
just with inheritance           
instead of protocols. So        
what if I did wanna send        
flipCard to vc, how             
would I do it or I can cast     
with any in exact same way?     
I can say, if I let some        
new variable called cvc,        
ConcentrationViewController     
equal the vc                    
as a                            
ConentrationViewController.     
Now cvc is                      
a ConcentrationViewController,  
I can send it flipCard.         
So same way I did with Any,     
I'm checking to see             
if it's possible for            
this var to be converted,       
in this case downcasted.        
This is called downcasted, to   
a subclass of that thing, so    
I can interact with it as       
that subclass. Same thing       
happen here with protocols, we  
could do that same thing with   
the car in the movable.         
We could had a movable var and  
try to cast it as a car.        
And if you were successful,     
then we can send a change oil.  
But if it was a shape and       
that failed,                    
we would return nil and         
we would not be able to do it.  
So                              
you're gonna see us doing this  
casting not as much with Any,   
some with Any, but a lot        
of time just down casting.      
Because we have some function   
that takes some super class     
and we pass a down              
cast subclass into it.          
And we're gonna down cast       
it to look at the subclass      
in case it is that subclass,    
then we can send it messages.   
All right, so that's it for     
Any and Castings object.        
The last last slide that I      
have here before we dive in to  
views, is just four other       
interesting classes that        
you should know about in        
foundation. One is NSObject.    
NSObject is the root            
class of all classes from       
Objective-C. All the things     
like UIViewController,          
all the UI kit classes,         
all those things that were      
developed in                    
the Objective-C world, and      
are compatible still with       
Objective-C. Their root class,  
the thing they inherit from     
eventually at the top,          
is NSObject. In Swift, no       
requirement to subclass from    
NSObject, although there's      
a few tiny esoteric APIs that   
ask you to pass a class in,     
that has to implement           
NSObject. And I'll explain      
them to you when we get to it,  
but normally your Swift class,  
like remember concentration     
that class, we originally made  
it. It didn't inherit from      
NSObject. It didn't             
inherit from anything.          
When it was a class, we         
converted it to struct later.   
And that's perfectly            
legal in Swift,                 
that was not true               
in Objective-C.                 
In Objective-C pretty much      
all classes had to inherit      
from NSObject, because some     
of the runtime was built into   
this class rather than being    
in the actual runtime like it   
is in Swift. Okay, second       
interesting class is NSNumber,  
in Objective-C when you pass    
numbers around you actually     
pass them with this class.      
NSNumber, it's a class so       
it's a reference type.          
You didn't have double and      
int as classes.                 
You had C like doubles and      
ints in Objective-C, but        
you didn't have that. So if     
you wanted to pass something    
in an object oriented way, you  
had to pass this NSNumnber.     
Now it can represent any kind   
of number, floating point       
number, integer, anything.      
It's a kind of a generic        
number holder, even a boolean   
it can hold in there.           
Now it's really awesome is all  
the API throughout iOS that     
takes an NSNumber and there's   
a lot of it, automatically      
bridged to the Swift types.     
So if you have an Objective-C   
based API somewhere in iOS      
that takes a number as          
an argument, you can pass a     
double in there. Or an int, or  
whatever it's expecting,        
whatever it's supposed to be.   
You don't even tell,            
you won't even know,            
you won't even see NSNumber     
because the documentation       
is already being converted      
as well to show you.            
And similar, when things        
come out, if something comes    
out of the API as an NSNumber,  
you can work on it as           
a double or an int, or          
whatever is appropriate and     
it work just fine. But I just   
mentioned in case you see it    
and wonder, what is that?       
Is this old Objective-C         
generic number holder?          
It's easy to see create         
one from a double or            
int by just using               
an initializer, right?          
NSNumbers sub 35.5,             
that's gonna give you           
an NSNumber with                
the double 35.5 in it.          
And you can get the values out  
with vars on the number like    
intValue, doubleValue,          
boolValue, they will give you.  
The return in a Swift           
type double, int, bool or       
whatever. Okay, Date.           
Some of you already know about  
Date because you did the extra  
credit maybe, in assignments 1  
or 2. Date is just a way to     
represent any date and time.    
You know internally it's        
represented, I think,           
like Number of seconds since    
1970 or something like that.    
It's great for doing that,      
it's great for even small       
amounts of time because the     
date includes the time down to  
small you know,                 
sub millisecond times.          
But I just want you to note     
that with date there's          
other classes that go along     
with it like Calendar,          
DateFormatter, DateComponents.  
DateComponents will give        
you things like the month and   
things like that. And           
why are there all those other   
classes? Well because date,     
if you're gonna put it in       
your UI, you have to be very    
careful. Around the world,      
dates are represented very,     
very differently, and it's not  
just that the name of a month   
is different in                 
a different language.           
It's that other locale,         
we call them around the world,  
use completely different kinds  
of dating systems. Maybe even   
a completely different          
calendar than we use. So        
you really have to be careful   
if you're gonna put date in     
your UI to understand all       
of these other classes.         
And there is plenty of          
documentation how to do it.     
But, and it is extra work.      
Now if you're just using date   
internally to like              
keep track of how               
long your Concentration move,   
or set game move is taking,     
obviously you don't need any    
of that other stuff. And        
finally there's data.           
Data is just a bag of bits,     
we use it to transfer data      
around a lot inside iOS API.    
For example if we got           
an image from the Internet,     
from some URL, it would come    
in as a big bag of bits. And    
we have classes like UI image,  
which I'm gonna                 
talk about today.               
That can look into              
the bag a bit and               
say, that's jpeg data and       
make an image out of it. Or     
look into a bag of bits, you    
know we have formatters that    
look and say that's json data.  
Good, who knows what JSON is,   
raise your hand if you've       
heard of JSON, okay,            
great. So that's JSON data, we  
interpret it as JSON data. So   
that's what this                
data struct is,                 
it's just a bag of bits, and    
there's lots of methods to      
convert it to and from other    
kinds of things. That's it, so  
that's all I wanted to mention  
is those quick things.          
Now we can dive into our        
main topic today which is       
a really cool one,              
which is Views. All right, so   
I don't want you to be          
confused about the word view.   
I'm using it in two contexts.   
One is MVC.                     
One of the letters there is     
V for view. That means that     
bunch of generic minions of     
your controller. That View,     
capital V View,                 
contains a lot of views.        
These views that I'm talking    
about, and what by these        
Views, I mean a subclass of     
the iOS class UI view. So       
that's what we're talking       
about today is these Views,     
these things in an MVC's view.  
Sorry for                       
the terminology being           
the same there but same word,   
somewhat different meanings     
there. So what is a view?       
What is a sub class of UIView?  
It's essentially just           
a rectangle on screen that      
defines a coordinate,           
a coordinate system. And        
this is a coordinate system     
you're gonna use to draw, and   
it's also a coordinate          
system for                      
getting multi-touch events,     
right,                          
with the fingers on             
the screen. It's hierarchical,  
which means these rectangles    
live inside other rectangles,   
live inside other rectangles,   
right?                          
So the views inside             
views inside views.             
And you saw this                
with Concentration.             
We had that top-level           
view which was black, and       
then inside that                
we had stack view.              
Remember that?                  
So that was another view.       
Inside that stack view were     
three more stack views.         
Inside those three sections     
were four card buttons. So      
as the UI buttons, right. Plus  
you had other views like your   
new game button, score, flip    
count, those are all views.     
And they are all kind           
of in each, you know,           
in a hierarchical               
representation.                 
So the way that if you look     
at a particular view and        
you wanna see who               
its superview is,               
in other words the view it's    
in. You just ask the view for   
the var superview. Okay.        
Now, it's an optional UIView    
because it might not currently  
be on screen, right? So, it     
might not be in a superview at  
this time. You could certainly  
add it. And then the other way  
around if you have a view and   
you wanna say, what are all     
the subviews in it?             
Like you wanna ask              
our blackview where,            
show me all your subviews like  
this top level stackview and    
the flip count, label and       
the score, and the new game     
button. You get that with       
another view var called         
subviews, which is, as you can  
see, an array of UIView. Okay,  
so it's very simple to manage   
this. There is also a UI        
window which is like way up at  
the top, but we never pay any   
attention to that in iOS. It's  
not like the Mac where you      
have lots of windows on         
a big desktop. The UIWindow,    
the only time you probably      
ever care about that maybe if   
you had an app that like        
projected part of itself out    
onto external screen or         
something. But forget that. So  
in this class we won't          
even mention UIWindow.          
It's probably subclass          
UIView anyway,                  
but we don't really talk about  
it. Now this hierarchy of       
views inside views, you build   
in Xcode in interface builder.  
Right, you saw how we           
built in Concentration,         
we drag things out, we clicked  
the embed stack view button,    
that kind of staff. So that's   
how we build this hierarchy,    
put views inside views          
99% of the time.                
But it can be done in code as   
well. And in your assignment    
3, I am gonna ask you to do     
both. Build view hierarchy in   
an interface builder like you   
did in concentration. But       
then also do some in code,      
as well. And                    
the way you do that is by just  
saying addSubview to a view,    
and it will add that view       
as one of the subviews.         
The only tricky thing here is   
when you wanna pull it out for  
If you wanna pull a view        
out of the view hierarchy,      
some reason.                    
you send that message           
to the view itself.             
Okay, you send it to the view,  
you want to remove and          
you say remove yourself from    
superview, with this remove     
from superview. So              
it's a little different there.  
You send add to the enclosing   
view but you send               
remove to the actual view       
itself. Now where does this     
view hierarchy starts. What's   
the top containing view?        
Well of course that's like the  
black view in concentration,    
right, that very top view. And  
there is a very important var,  
in UIView controller,           
called view.                    
And that view points to         
that black one at the top.      
And it's automatically          
wired up for                    
you in interface builder, so    
you can always start there and  
kinda of work your way down     
through the hierarchy,          
looking at the sub-views and    
going on down. So               
var view which is a UIView,     
in UIView controller,           
very important var to know if   
you want to access your view    
hierarchy directly. Now of      
course, you can also access     
your view hierarchy at any      
point with an outlet. Right,    
if you create an outlet         
like to a stack view,           
now you can look right          
at the stack view, and          
then start looking at its       
subviews if you want,           
you don't have to start at the  
top and start looking down.     
You can use an outlet,          
just go to any view you want    
at any time. All right,         
let's talk a little bit about   
initializing a view, right?     
Getting initialized. Normally,  
as usual, we try to avoid       
doing init as much as we can,   
with all those other ways we    
know. If you have to do a view  
initializer cuz you just,       
a var that you just no way you  
can initialize it using all     
the other ways we know. Then    
you have to understand that     
view has two initializers,      
init with frame and init with   
coder. Init with frame is       
the initializer you usd         
to create a view in code.       
Init with coder is the          
initializer that's used when    
you build your view in          
an interface builder and        
it gets free stride and then    
your app runs. When it runs,    
it gets initialized with        
init with coder. The coder,     
NSCoder is a protocol that      
handles this mechanism of       
freeze drying with              
interface builder and           
then re, resurrecting it        
when your app runs. So          
you have to implement           
of both of these. And           
the reason you have             
to implement both               
of these is cuz init with       
frame is a designated           
initializer, okay. And so if    
you ever created a view from    
code, you need, if you want     
your code to execute, it's      
gonna have to do it. And then   
init with coder is a required   
initializer because it's part   
of a protocol that UIView       
implements, this NSCoder        
protocol you see. Remember,     
if you employ a protocol and    
it has an init in it,           
it's required, okay. So you'd   
have to implement them both.    
Now you can have some other     
function like set up or         
whatever and call that setup    
from them both. Although,       
sometimes it's not that simple  
because if you're using         
this mechanism to initialize    
your own vars, you're supposed  
to initialize your own vars     
before you call super.init.     
Okay, so you are gonna have to  
initialize those vars inside    
these inits. Maybe you might    
have slightly duplicated        
code there, doing that.         
But hopefully,                  
you can avoid this init in      
UIView entirely. Okay, another  
alternative to initializing     
the UIView is awakeFromNib().   
Now awakeFromNib() is           
actually a function,            
that is sent to every single    
object that comes out of        
an interbase face               
builder file.                   
Every UI button,                
every UIView controller,        
everything that comes out of    
there, when it gets unfreezed,  
it gets sent awakeFromNib().    
Now the only thing about        
putting initialization there    
is, it will only work for       
views that come out of          
an interface builder file.      
If you create a view with       
init when framed from code,     
if you created one,             
this won't get called. Okay,    
this only happens when you      
get unfreeze write interface.   
NIB is kind of really old name  
for interface builder files,    
the IB and NIB meant            
interface builder. Okay, so     
that's it for initialization    
of views. All right,            
now let's talk about how we     
draw. We have this UIView.      
Why do we want it?              
Well, we wanna draw.            
How do we draw? Before I        
can tell you how to draw,       
we've got to talk               
about some types,               
four very important types.      
Okay, they all start with CG,   
like this one, CGFloat.         
CG stands for Core Graphics.    
Core Graphics is the            
underlying drawing system for   
normal 2D drawing in iOS.       
There are other                 
drawing systems for doing 3D    
and other things. Not gonna     
talk about those cuz we only    
have so much to talk about.     
We're just gonna talk about     
the base 2D drawing system,     
and it's called core graphics.  
So core graphics has these      
four types, they're just        
critical to be in the say       
anything about drawing, one     
is CGFloat. So all drawing is   
in an accordance system that's  
floating point numbers. So      
you're drawing in a floating    
point coordinate system,        
not integers,                   
they're floating points.        
When you say where you wanna    
draw, your every point you're   
just dealing with floating      
point numbers. And for          
those floating point            
numbers have to be CGFloat.     
They cannot be doubles or       
regular float, they have to be  
CGFloats. Luckily, there's      
an initializer for CGFloat.     
We'll let you create            
a CGFloat from a double, but    
CGFloat is the fundamental,     
kind of coordinate value,       
a floating point co-ordinate    
value. All drawing, all your    
code that's drawing is gonna    
have CGFloats. Now, of course,  
there is CGPoint, which is      
just a struct with two things   
in it, x and y, which are both  
CGFloats. And there's CGSize,   
which is a struct that has two  
things in it, two CGFloats,     
width and height. Okay, so you  
got float, CGFloat the base     
thing, then you got point and   
size. And of course,            
you can combine point and size  
into very important CGRect.     
Now CGRect is just finds        
a rectangle obviously,          
including your views entire     
bounds, that rectangle or       
any rectangle you wanna draw    
inside your quadrant system     
you're gonna use this. And it   
has a number of initializers    
including initializing          
by origin and size.             
Also intializer that takes      
xy width, height, etc.          
And it also has a whole         
slew of other vars and          
functions for manipulating      
rects, like vars like minX,     
which gives you the minimum     
x value of your rectangle.      
Or, intersects that             
takes another rect and          
returns a bool whether          
the two rectangles intersect.   
There's also intersect          
which returns a new rect        
which is the intersection of    
two overlapping rectangles.     
It also has contains CGPoint,   
which will tell you whether     
there's a point, that is        
point is inside CGRect. So      
there's tons, this probably     
two or three dozens methods so  
definitely check out            
the documentation CGRect,       
because it'll make your code    
a lot cleaner. And actually,    
you're gonna see in the demo    
that I do on Wednesday.         
I actually even extend CGRect   
to add five or six more         
a little convenience functions  
because CGRect turned out       
to be so important in all       
the code that you write.        
When you're doing drawing. So   
now you know those four types,  
let's talk about the            
coordinate system we're gonna   
be drawing in here. The most    
important thing to know         
besides the fact that it's      
floating point precision to     
draw is that the origin is      
in the upper left, not lower    
Left. The lower left would      
be Cartesian coordinates,       
you know, like you have in      
Math class. Lower left alk,     
also happens to be the          
coordinate system on the Mac,   
okay. But in iOS,               
it's in the upper left,         
and that means that increasing  
values of y go down towards     
the bottom of the screen. So    
for example, I got this point   
over here on the side there.    
See it up there, 500, 35.       
It's 500 over and 35 down,      
right, way over and way down.   
So that's x of 500, and it      
actually really would be 500.0  
and 35.0 cuz they're floating   
point values, right? Okay,      
the unit in this coordinate     
system are called points.       
Points are not                  
the same as pixels.             
Pixels are the little dots      
that the screen is made of.     
Some screens have a lot         
of little pixels, very,         
very high resolution,           
what we call Retina Displays.   
You've probably heard that      
phrase. Lots of pixels per      
point. Why is that good? Well,  
because remember you can draw   
on floating point boundaries,   
so you can draw at 27.3, 27.6,  
28, right? You could be         
drawing in between points. And  
you get these very              
smooth curves or                
whatever on a Retina Display.   
On a lower res display,         
maybe there's only one pixel    
per every point, and so         
it's kind of more jaggy when    
you draw. But you don't draw    
on pixel boundaries,            
you draw on point boundaries.   
That way, even if you had       
a lot of pixels per point,      
it looks the same size          
basically as on a lower         
resolution device. Okay, it's   
not as smooth as on a high      
resolution device but it's the  
same size cuz it's zoom point.  
You can find out how many       
pixels per point your device    
has by using UIView content     
scale.factor who turns          
a float, it's currently         
gonna either be one, two, or    
three. And it's gonna tell you  
how many pixels are are there   
per point. All right,           
the most important rectangle    
in all of UIView is bounds,     
it's var on UIView to CGRect.   
It tells you the bounds,        
the coordinates of your         
drawing system, the origin and  
the width and height in your    
own drawing coordinate system.  
And one thing you have          
to understand is,               
different views have            
different coordinate systems.   
Okay, they each have their      
own coordinate system,          
this bounds is in yours.        
So when you're drawing,         
you always use bounds. Now      
there are a couple of other     
things like frame. Var frame,   
sounds a lot like bounds.       
Frame has nothing to do         
with your drawing. Nothing,     
it's a Rect, but has nothing    
to do with your drawing.        
The frame is where you          
are in your superview.          
So frame this not even in       
your coordinates system,        
in it's your superview's        
coordinate system.              
Says, where you are?            
Similar with center.            
Center is not the center        
of your drawing area, it's      
the center of view in your      
superview. So frame in center   
are, where you are? Bounds      
is the place you're drawing.    
Don't get these things          
confused. I have a slide down   
here, go through it quick,      
we never use frame or           
center to draw because it has   
nothing to do with drawing,     
it has to do with positioning.  
And you might think that        
the frame and the bounds        
are gonna be the same size,     
but views can be rotated. And   
if you imagine rotating your    
view, the bounds get rotated    
with, okay, so they stay the    
same size, but the frame now    
has to get bigger. To totally   
enclose this because it's       
a diamond shaped, right, View   
B is a diamond shape. Okay, so  
the frames' sized-out width     
and height are not the same     
necessarily as the bounds'      
sized width and height.         
Don't ever think of             
them as the same.               
If you ever use your frame      
to draw in this class,          
you'll get dinged,              
that is just wrong.             
All right, so now we know       
the bounds of where we          
are drawing. We know we have    
this coordinate system in       
the upper left. How do we       
create one of these views?      
Okay, we wanna create one.      
Well,                           
I told you that you mostly do   
it in Interface Builder, but    
if I have a custom view. Let's  
say I have a custom view,       
draw something                  
special to just me.             
How do I drag that out into     
Interface Builder? Right,       
Interface Builder's got that    
nice list in the lower right    
corner of UIButton, UILabel,    
all those cool things.          
My view's not gonna be there,   
right?                          
So how do I make one? Well,     
it turns out you drag out       
a generic one. Currently,       
as of this my speaking,         
it's the second from            
the bottom in that long list.   
It's called UIView down there.  
You drag a generic one out and  
then you're going to inspect    
it, but you're gonna use        
a little different inspector    
in the upper right than you     
usually do. It's not            
the Attributes Inspector,       
it's the Identity Inspector.    
I think it's the tab,           
just one to the left of         
the Attributes Inspector. And   
in there,                       
the top thing is going          
to be the class of the thing    
you're inspecting and           
it's gonna be UIView when you   
first drag it out. And you're   
just going to change the pull   
down there to pick your class.  
So now you have a view there,   
but it's of your class.         
That's how you're gonna create  
one of your custom views. Now,  
the other way you can           
create views is in code.        
And again, I'm gonna ask you    
to do this both ways in your    
assignment three. And you do    
that just by calling the frame  
UIView with frame initializer   
that we talked about before.    
You can also set UIView         
open parenthesis, close         
parenthesis, then your frame    
will be 0000, upper left,       
no size. And you can then       
just set that frame var,        
that I talked about a couple    
slides ago, to position and     
size, this view in              
the super view. Okay,           
just always remember            
the frame, though,              
is in the super view's          
coordinate system,              
it's saying where you are.      
Nothing to do with              
your drawing,                   
just where you are.             
Okay, so here's an example.     
I'm gonna create a UILabel      
encode. Okay, UILabel, you      
know what that is, right? It    
shows text, that's the thing    
that said flipped colon 0,      
that was a UILabel. Of course,  
UILabel inherits from UIView.   
It's a rectangular area on      
screen. All rectangular areas   
on screen are UIViews. So, I'm  
gonna create a rectangle to     
say where it's gonna be.        
This rectangle is gonna be in   
the super view's coordinate     
system. In this case,           
I'm gonna put the label         
at the very top level.          
In other words, the black view  
of Concentration, I'm putting   
it right over that level. So    
this 20 across and 20 down and  
a width of 100 and height of    
50, that's in the black views,  
the top level views coordinate  
system. And then I created      
a UILabel using that frame. I   
set the label's text to hello.  
Nothing's happening on          
screen right there, yeah.       
Now, I need to add it as a      
subview of that black view, so  
I'm gonna assume this code      
is in a view controller and     
I'm gonna use that              
very special var view.          
And say, view, add subview      
this label. Now that            
UI label gets added as a        
subview of the top level view,  
the black view in               
concentration,                  
it's white here, and            
it gets put at 20, 20,          
150 in that top level views     
coordinate system. Remember,    
upper left is 00. So, that      
means down from the upper left  
corner. Everybody got that?     
So that's how you add view,     
it's very easy just add         
subview. That's how you put     
view on screen on code. All     
right, so when would I wanna    
create my own UIView subclass   
versus just using UIButton or   
UILabel?                        
Those are UIView subclasses.    
Well, if I obviously want       
to do custom drawing or         
if I want to handle some        
custom touch events,            
pinches or                      
something like that.            
I'll talk about handling touch  
events on Wednesday, but        
today we're gonna focus on      
drawing. So we're going to do   
all drawing today. So to draw,  
it could not be easier,         
there's only one way to draw,   
okay, in all of iOS. Which      
is you override this function   
in UIView and implement it.     
That is the only way to draw.   
You can't call any functions    
that draw or anything           
outside of this method,         
it's the only way to draw.      
So that makes really simple,    
you don't have to worry about   
any other mechanism cuz this    
is the only one there is. And   
so inside this draw method,     
you're going to draw            
in your bounds,                 
whatever custom                 
drawing you do. Okay,           
never call this method ever.    
This method,                    
you override and                
implement your drawing,         
you never call it. If you       
want your view to be redrawn,   
because something about you     
has changed, you call one of    
these two methods on yourself,  
setNeedsDisplay or              
setNeedsDisplay with rect.      
Okay, and                       
that tells the system, hey,     
my view needs to be redrawn,    
please, redraw it.              
So, only the system, only iOS   
calls your draw and you can     
make it call it, or tell it     
you want it to call it anyway,  
by calling setNeedsDisplay.     
Now notice this rect, see       
the draw rect. What is that     
rect argument, both up on draw  
and down in set needs display.  
That is purely an optimization  
rectangle, okay. That's if,     
for example, you had another    
view on top of view and         
it went away and it exposed     
a little rectangle of view,     
the system would call your      
draw with just that rectangle.  
But you are allowed to redraw   
your whole view if you want.    
But if you can be efficient     
about only drawing              
the rectangle                   
that was exposed,               
then you can be efficient. So   
it's purely an optimization.    
You can ignore it if you want,  
just draw your whole view.      
So if you have a simple         
view that's easy to draw,       
doesn't use a lot of resources  
and not 3D graphics or          
something, then you can just    
ignore that rect. All right,    
so how do I implement this      
draw rect? Okay, I overwrite    
it now I want to draw.          
So how are we gonna do it?      
We're gonna do it               
using core graphics,            
this underlie drawing level     
layer. And the basic way        
to do it is, you get what's     
called a drawing context and    
you ask that context            
to draw lines and               
stuff, okay. Now, there's also  
an objects orientated way to    
draw with a class               
called UIBezierPath.            
UIBezierPath, same concept.     
It's just putting a little bit  
of an object or in the way you  
can build an object that        
contains some drawing.          
Which is nice if you wanna      
repeatedly draw that object,    
maybe with different colors,    
whatever. So let's talk about   
the fundamental core concept    
of drawing in core graphics,    
how do we do it?                
The number one thing about      
core graphics is that it's      
context based, so you have to   
get a context. UIBezierPath     
will automatically              
get the context for             
you, but                        
if you don't use UIBezierPath,  
you have to get a context.      
Now, in drawRect,               
you can you use this            
Swift global function,          
UIGraphicsGetCurrentContext     
and it will give you a context  
to draw, okay. But there could  
be other contexts, printing or  
drawing on and                  
off screen buffer,              
I'm not gonna talk about        
those, but there are other      
ways to get context as well.    
But when you're in drawRect,    
it's easy. You just call        
this one global function,       
it will give you the context    
you are currently drawing in.   
Okay, once you                  
have the context,               
now you use the context to      
create what are called paths.   
Paths are just arcs and         
line to's and                   
then move to's, which is        
like jump over a little bit.    
It's just a combination of all  
those, that is what a path is.  
So you're gonna                 
build some path.                
Then, you're gonna set a bunch  
of drawing attributes,          
like the color you want to      
draw in, any fonts, kind of.    
That's a drawing attribute,     
we'll talk about fonts in       
a bit, but line widths,         
textures, things like that.     
You set all those things        
up and then you do one of       
two things with your path, you  
stroke it or you fill it. So,   
stroke it means draw a line     
along my path, you know,        
with a certain line width and   
color, and fill means fill in   
the area that my line           
encloses. Believe it or not,    
this is the only way to draw,   
basically, in.                  
Core graphics and you might     
like, wow, that seems really    
limiting. All I can do is arcs  
and lines and fill them in and  
stroke them, but it's amazing   
what you can do when you build  
on top of that primitive        
powerful mechanisms, okay, and  
we will talk about that.        
So UIBezierPath does the same   
thing, it just does a lot of    
it under the covers but it has  
methods for setting line with,  
and things like that.           
It has method to stroke and     
a method to fill, and           
a methods to do arc to and      
line to and all that thing. So  
it's just a kind of arbitrated  
collecting bag of that. So      
let's look what                 
the code looks like.            
To draw a triangle              
using this mechanism.           
So first time,I will do with    
UIBezierPath. I'm gonna create  
UIBezierPath,it has a lot       
of initialization but           
I'm gonna use the one that      
just create an empty path.      
That create a new,              
there is nothing in it.         
Now I am gonna move around,     
I am gonna start by moving to   
a point you see that            
80 across and 50 down.          
Let us assume that this screen  
is 160 points across and        
you know 300 or 400 high. So    
I am moving halfway across and  
50 points down from the top     
my margin is up on the left.    
Now am gonna add a line         
down to 140 over,               
almost to the edge of           
the screen up there, and        
150 down then I'm gonna add     
another line. You see how       
I'm just calling functions on   
my UIBezierPath to add lines,   
right? So there is another      
one over here. Then I'm gonna   
close my path so there is a     
method in UIBezierPath called   
close which draws a line        
back to where you started,      
whatever that was.              
So, I'm gonna close my path.    
And there's a lot of tons of    
methods in UIbezierPath you     
have to go look at              
the documentation. But here's   
a simple, those are simple      
method usage, right? Now I      
kind of been tricking you       
because you'd look at this and  
it looks like as I called       
these, it draws on screen, but  
no. I just wanted to kind of    
give you visualization what's   
going on. In fact, when I did   
all that, nothing happened on   
screen. There was absolutely    
nothing happening,              
all I was doing was building    
this UIBezierPath object up.    
If I wanna appear on scree      
I have to set my drawing        
attributes and                  
tell it to stoke or fill. So    
let's do that. Now we set our   
colors both our fill color and  
stroking color using            
UIColor class. So               
we don't set it on              
our UIBezierPath,               
we actually use color and       
we say things like              
UIColor.green.setFill.          
Well, green is a static         
var on UIColor,                 
meaning it's a class            
like a class color,             
just like get unique            
identifier was in card. And     
it just gets the green color    
and it has about 10 or          
12 predefined colors, red,      
green, blue, magenta, cyan,     
that kind of stuff.             
We could also make colors.      
We could use a color            
literal there.                  
Remember when we did the color  
literal? Perfectly legal to     
say colorLiteral.setFill. So    
we're setting our fill color    
and our stroke color. So        
we're gonna fill with green.    
Our triangle is gonna be        
filled with green and           
the line is gonna be            
drawn With red and              
I'm also going back to          
the BezierPath and saying,      
set the line with two three     
points wide on a high           
resolutions play that will      
be nine pixels wide. So         
it's a very thick line,         
not that thick that but, so     
now that I have set these       
things up now I can stroke and  
fill. So let us first fill And  
when I feel I get this notice   
there's no line around          
the edge I just get the fill    
of my path that I made.         
And then when I stroke now I    
get the red 3 point wide line   
around. Yeah?                   
>> Where this is                
written?                        
>> Where this is written?       
Like where you put this?        
In your draw rect.              
In that draw method,            
that we override in UIView,     
that's where this code goes.    
>> So, when I drag a UIView     
out to the storyboard, do I     
have to make an outlet to,      
like, have-                     
>> Okay, so the question is,    
when I drag a UIView out        
into my storyboard and          
I set it to my custom class,    
do I have to like do an outlet  
or something? No, you just,     
in your custom code, implement  
your draw with that kind of     
optimization rect argument and  
put this code in there, and     
every time the system has       
your view on screen it          
will draw this. Now it's very   
efficient it's only gonna ask   
you to draw once unless things  
change, but it's gonna draw it  
for you. So all the whole,      
all the drawing is on demand,   
right? The system asks you to   
draw, it calls your function,   
you implement this code and     
it draws on demand.             
You never force draw.           
The only way you can            
kind of force drawing,          
is that setNeedsDisplay.        
And even that's just telling    
the system to please draw me    
as soon as possible, but not    
instantly. It's all on demand   
drawing. So, this is how        
you would implement. This code  
would be in your draw rect.     
We call it dra_rect, it         
used to be called draw rect.    
Now it's called draw under      
bar rect, but I suppose we      
can call it the draw method,    
but we call it dra_rect,        
it's got that rect argument,    
okay, that optimization.        
All right, now you can use      
UIBezierPath also to create     
some very common paths like a   
rounded rectangle which we'll   
use in our demo cuz we're       
gonna do a playing card, which  
has a rounded rectangle. You    
can also do circles, ovals,     
things like that using other    
initializers of UIBenzierPath.  
Note that you can use           
your BezierPath to clip         
your drawing. You'll            
definitely want this for        
your homework,                  
pay attention here. So          
what that means is you draw     
some shape like your triangle.  
And if you send add             
clip to your path,              
now all future drawing will be  
inside that triangle. Even if   
you draw outside, anything      
outside gets clipped off.       
So that can be really           
convenient for your homework.   
That's my hint for you.         
You can also do hit detection   
like is this point in           
the triangle, right?            
Using this contains             
point method and                
a lots of other stuff.          
So check the documentation for  
UIBezierPath of the things      
that you can do.                
All right, let's go and talk    
about UIColor, right? Okay,     
first setting the fill and      
stroke something like that.     
We know a lot of ways to        
create colors. Color literals,  
also the static function I      
mentioned. You can also create  
them with initializer           
to take RGB values.             
Or HSB which is hue             
saturation and brightness or    
even a pattern. You can create  
a color that's actually         
a pattern some image,           
just like repeated, right,      
which is kinda cool. And        
we also know that views have    
the background color, right?    
We set the background color     
of our base view in             
Concentration be black.         
We set the background color of  
our buttons to be orange, so    
there's a var for that of       
course, in view. Colors also,   
importantly, can be             
transparent. A transparent      
color you can kind of see       
through it a little bit and     
we specify transparency using   
something called alpha.         
How many people have heard the  
term alpha drawing? Okay, so    
most of you know this, great.   
So, we use alpha. Alpha of 0    
means fully transparent, and    
alpha 1 means fully opaque and  
we can have any number          
in between. The way get         
a transparent color, is take a  
color you've got, like yellow   
let's say right there, and      
you send it the message, or     
the function,                   
withAlphaComponent. And         
it will give you a new color    
that has that transparency.     
Now you can draw with           
that transparency.              
If you want to draw in you      
view with transparency,         
though, be very careful.        
Because,                        
the system assumes by           
default that your view only     
draws opaque. It only draws     
with fully opaque colors.       
If you actually draw            
with transparent colors,        
you have to set a var on the    
view called opaque to false.    
Now why does he do this? Well,  
imagine how much more CPU and   
GPU intensive it is to draw     
with transparency because now   
the views behind you have to    
be composited with your bits,   
and you know the compositing    
not cheap, all right?           
The GPU got a lot of            
work to do there, so            
that's why it says to assume    
everything is opaque and        
that everything overlapping     
doesn't have to be composited.  
And, so if you wanna            
draw with transparency,         
which is fine. It's legal.      
It's not that expensive that    
you would never wanna do it.    
But just make sure you          
set this opaque to false.       
And you can do this             
in interface builder.           
You can click on the view,      
and one of the things in        
the inspector over there is     
whether it's opaque and just    
turn that off. By the way,      
you can make your entire view   
transparent, if you want,       
by setting it alpha,            
so views have alpha.            
That means all your drawing in  
there will be                   
somewhat transparent.           
That's kind of a cool feature.  
All right,                      
brief mention about layers.     
So UIView's drawing mechanism,  
is actually built on another    
whole system I'm not            
gonna talk about, called Core   
Animation. And that's because   
everything you do in a view     
can be animated. Views moving,  
transparency happening, all     
this stuff can be animated and  
there's a whole layer for       
doing that. And so,             
the UIView, we see a top        
level API for it, but there's   
actually a whole other API for  
drawing called the CALayer,     
Core Animation Layer API.       
And I actually mentioned this   
in the hints of Assignment 2,   
you've already seen this.       
There's this var in UIView,     
it's in button because          
button's a UIView,              
called layer, which gives you   
the layer, the CALayer, that's  
being used. Now I'm gonna       
talk all about animation,       
hopefully next week,            
maybe the week after, and       
we'll get into some of this     
stuff. But you already know     
from Assignment 2 that there's  
a few really nice vars in       
the CALayer like cornerRadius,  
if you wanna put a rounded      
rect on your view, or the       
borderWidth and borderColor.    
By the way, you notice that     
the borderColor there was       
a CGColor, not a UIColor.       
CGColor means it's a Core       
Graphics color, why is that?    
Well, that's because this       
whole layer mechanism,          
Core Animation,                 
is below the UI kit layer, and  
it built on top of              
the Core Graphics layer. So     
it can't really use             
the UIColor struct              
because it's kind of above it   
in the hierarchy of frameworks  
depending on each other,        
so use a C, CGColor.            
Luckily, UIColor is also above  
Core Graphics. So it has a var  
called CGColor, which gives     
you itself as a CGColor, and    
I showed all that in            
the hints of your assignment,   
right? Okay, so that's a layer  
thing, we'll talk about,        
more about animation later.     
Let's talk a little bit about   
the transparency and how that   
works, like which views are in  
front of which other views,     
right? If I have a transparent  
view, and it shows the one      
behind, which is behind?        
That's all determined by the    
order of the subviews list.     
Any view that has subviews      
has an array of them.           
The first thing in that         
array is the back. And          
everything else is              
one step in front,              
the last thing is the one       
in the very front.              
So if you have multiple         
subviews of your view and       
they overlap, it's the one      
in back is the first one in     
the subviews list. So you can   
reorder the subviews list and   
move them. Move the one from    
the front to the back or        
whatever, so you can control    
that transparency effect.       
Also, even if there's           
no transparency,                
if the views are on             
top of each other and           
they happen to overlap.         
A lot of times when we          
have multiple subviews,         
they're are all side by side,   
they don't overlap,             
but they could. Oops, they      
could overlap, and if they      
did, then that subviews         
will tell you the order,        
which ones are in the front.    
You can completely              
hide a view without taking it   
out of the view hierarchy,      
with isHidden. If you say to    
a view, this is a var on view,  
if you say view isHidden        
equals yes, it will not appear  
on screen. It'll still be       
in the view hierarchy,          
still in the subviews list.     
It'll still have a superview,   
but it won't there, and it      
won't get any gestures either.  
So you won't see its drawing,   
you won't get any gestures,     
it'll be hidden. And            
you'll be surprised how common  
it is to wanna do these.        
You put a view in the view      
hierarchy somewhere,            
you hide it, then when some     
condition is true, it appears,  
probably animated. Things       
appear, that's a common way to  
build an interactive UI.        
All right, so we know how       
to draw with these arcs.        
What about drawing text? Well,  
actually text is just some      
font designer, moveto, lineto,  
curveto, okay. That's all the   
character, every character in   
the text is just a bunch        
of little moveto, lineto's.     
Luckily, some font designer     
somewhere did those all for     
you, or that would be           
incredibly tedious for          
you now, wouldn't it? So we     
wanna be able to draw though    
using these wonderful moveto,   
linetos, which are the glyphs   
in a font. So how do we do      
that? Well, before I even dive  
into that, remember that        
UILabel draws text real well.   
And there's no reason you       
couldn't make a UILabel be      
a subview of your view, and     
thus draw the text that way.    
Okay, that's a great way to     
draw it, because UILabel's got  
all the incredible amount       
of center text alignment,       
and you can control the color,  
you can put an attributed       
string on that label.           
You've got complete             
control with that.              
The only thing is you have to   
make sure that you keep that    
UILabels frame in the right     
spot in your subview.           
You know, as, it's one of your  
subviews, so you've gotta make  
sure its frame is kept          
in the right space. But         
that's a great way              
to draw text, so                
don't forget that. But I will   
talk to you now about how to    
draw in your draw rect, and     
use attributed string. Okay,    
so you just create              
AttributedString,               
and you send it                 
the message draw, and           
it will draw at the point you   
say in your current context.    
So drawing text                 
could not be easier,            
you already know how to do      
an attributed string, so        
you just create                 
attributed string here.         
My attributed string doesn't    
have any attributes here for    
slide space issue. But          
you could put your attributes   
on it, whatever, and            
then do draw(at. You can also   
do draw(in), and it'll draw it  
in a rectangle in the upper     
left corner of the rectangle.   
And then you can also get       
the size of the text by         
just asking the attributed      
string, what is the width and   
height necessary to fit         
this attributed string. So      
super easy to draw              
text in your draw rect,         
you just use AttributedString.  
Now I wanted to take a little   
time here about                 
AttributedString and            
circle back to what I           
said about it before.           
Remember I talked about         
how NSAttributedString is       
an old objective thing, and     
it uses NSString and then,      
we're using String? And String  
uses kind of a different        
encoding for Unicode            
characters and sometimes        
mapping between NSString and    
String. The indexing is         
different because we got        
wacky characters like emoji,    
that are actually               
multiple Unicodes,              
ugh, that whole mess,           
you remember that? Well,        
I'm gonna tell you a little     
bit how to get around that.     
You don't need it, you didn't   
need it for Assignment 2,       
you won't need it for           
Assignment 3.                   
Maybe I'll ask you to do for    
Assignment 5. But if I do       
wanna set attributes just on    
certain characters in my        
AttributedString, and           
it's a String, not a NSString,  
how do I do it?                 
Well, the answer is, this       
class right here, NSRange. So   
NSRange is the way you specify  
a range into an NSString.       
Okay, so this is an old         
Objective-C way of doing        
a range. In our world,          
we do Range.      
That's how we index             
into a string, right,           
because we know the strings     
are indexed by String.Index     
not by init. So we have this    
totally different thing,        
Range. And here   
AttributedString wants to do    
an NSRange of init because      
NSString was indexed by init.   
Okay, so how do we get from     
range of String.Index to        
NSRange of an init              
that matches, okay, so          
that the NSAttributedString     
matches our string. Well,       
we do it with NSRange,          
we do it with this right here.  
This is NSRange initializer,    
you see it,                     
NSRange initializer.            
It takes this firstWordRange,   
which is an Swift range of      
string.index. You see it goes   
from startIndex here over to    
indexOf, so it's a range. It's  
got the little ..< which is     
our nice range syntax there.    
So it takes a range and it      
converts it into an NSRange,    
but it needs to know            
the string that that string,    
those string.indexes are into,  
right?                          
So the combination of           
knowing the string and          
the string.index range. It can  
crunch on that and change it    
into an NSRange that will work  
in an NSAttributedString.       
So that's the magic. NSRange,   
use the initializer that takes  
a range of string.index and     
a string.                       
It'll give you back NSRange.    
Now you can call methods        
like in AttributedString,       
like addAttribute, which        
adds a single attribute at      
a certain range of characters.  
Look at the argument, range,    
nsrange, now you have an        
nsrange to give it. All right,  
fonts. Okay, fonts incredibly   
important in iOS. I cannot      
overstate how important         
fonts are to the look and       
feel of iOS. These are, I       
think are iOS 10 screenshots,   
and iOS 11 things have changed  
slightly, but not too much.     
But even in these screenshots   
you can see how important       
fonts is. They really make      
a difference to how your UI     
looks. So you have to           
pick the right font.            
So how do we pick fonts?        
Well, in iOS,                   
the most important concept      
with font is preferred fonts.   
There are about ten categories  
of fonts like body fonts,       
headline fonts, caption fonts,  
footnote fonts.                 
So there's these                
kinds of fonts, and             
you need to pick one of         
those preferred fonts for       
whatever environment you're     
text is in. If you're showing   
main information then it's      
probably the body font.         
If it's a little caption of     
an image, you're gonna use to   
caption font. Okay, so you got  
to pick the right font and      
use it. Now this is really      
easy to do Interface Builder.   
You just pick your label, or    
button, or text field, or       
whatever you're doing, and      
you go to inspector, and        
where it says font, instead of  
using system font, which is     
what we've always chosen,       
because I haven't talked to     
you about preferred font, you   
choose one of these things,     
body font, caption font,        
footnote font, etc.             
In your code you could          
do the same thing, and          
you do that using this          
static i.e class type method    
in UI font, called preferred    
font for text style, and        
that text style is headline,    
body, footnote,                 
whatever. This will give        
you back a UI font that you     
can put in your NS attributed   
string dictionary.              
One of the keys in there is     
the font, and you can use this  
as the font, when you're        
drawing text in your drawRect.  
Now one thing to be concerned   
about here is that the size of  
this font is variable.          
But you get old people like,    
okay, we're starting to         
hold our phones like this,      
as the years go by,             
cuz our eyes are giving up, so  
we like the fonts big. Then     
we can hold it all closer and   
see our fonts. Well, the way    
we do that is we go into our    
settings on our phone, and one  
of the settings under general   
there is accessibility, and     
we can say larger text, and     
we move the little slider, and  
now all the fonts get           
bigger in all the apps, but     
only the apps that play         
this game right, and            
use preferred fonts. So you     
wanna be one of those apps,     
otherwise, you're gonna         
lose the older folk from        
your demographic,               
of your people buying your      
app. So it's important to make  
sure that your UI also works    
when fonts get bigger and       
smaller, and the number one     
way to do that, auto layout.    
You know that auto layout       
where you put constraints,      
pin things to the edges. You    
wanna use good auto layout so   
as fonts get bigger, and the    
text field gets bigger, other   
things push out of the way and  
it uses the screen real estate  
properly. So you've only seen   
a little bit of auto layout.    
I'm gonna show you more auto    
layout at start of Wednesday's  
lecture.                        
You're gonna see more and       
more as the quarter goes by,    
but                             
that's a good way to make       
it work. Now what if you        
either wanna use some other     
font, some special font that's  
something that's maybe part of  
your marketing or whatever, or  
you want it to be bigger,       
or smaller I guess,             
than the standard size font     
that comes with a certain       
prefered font. Okay, well,      
UIFont does have a way to       
create a font by name like if   
you want Helvetica 36 point,    
you can say UIFont(name:        
"Helvetica", size: 36.0), and   
there's also a class            
called UIFontDescriptor.        
Has a lot of cool ways where    
you can take a font and         
say give me the Bold            
version of this,                
give me the Italic version,     
okay all of that stuff. So      
you can get your font this      
way. But if you do your fonts   
this way, you still want,       
when I go into my setting and   
make my font bigger, you want   
your font to get bigger, and    
look what font size this is,    
36. It's fixed.                 
So I need to somehow            
scale this font up              
if the user has put their       
slider to bigger, and           
the way you do that is with     
UIFontMetrics. So you create    
a UIFontMetrics object for      
the text style body, footnote,  
caption, whatever, and then it  
has very cool method called     
scaledFont, and you give it     
a font, like Helvetica 36,      
and it will give you back a     
new font, Helvetica 42, maybe.  
It's scaled based on what the   
user said. Okay, don't skip     
this step, otherwise,           
if you use a custom font,       
when people move that slider,   
your app's not gonna work, and  
people are gonna be like,       
I hate that app.                
I can't see any of the text     
and it's too small.             
There are also system fonts.    
We use those so far in our      
concentration demo. That's      
only for things like button     
titles, and stuff like that,    
that's not for user content,    
stuff that the user has         
generated, or requested, or     
something like that.            
Thos are preferred fonts.       
System fonts are just like      
buttons, things like that.      
What about images? We know      
how to draw lines and arcs.     
We know how to draw text.       
What about drawing images?      
Just like UILabel for text,     
there's another one             
called UIImageView,             
which lets you add an image as  
a subview. So you could use     
that to draw an image in        
your view if you want it,       
just do it as a subview.        
But if you wanna draw an image  
in your drawRect,               
you can do that too.            
You need a UIImage object.      
A UIImage represents an image,  
jpg, gif, whatever kind of      
image, it represents an image.  
Now, how do you get an image?   
There's a bunch of ways to do   
it. One way is to drag the jpg  
file, or whatever, into that    
Assets.xcassets file. Remember  
when we're doing our demo,      
and I put some things           
off in supporting files?        
One of the things I threw in    
there was the place where       
the app icon was. Well,         
you can drag other images in    
there, and along the left hand  
side will be all the names      
of them, and then you can       
call this method right here,    
UIImage named whatever, and     
it'll go look in that assets    
thing, and                      
find an image with that name.   
Now, this is a failable         
initializer.                    
It can return nil, and that's   
because it might not find       
that particular image in        
there. So you have to say       
usually if let to do that.      
How else can you get an image?  
Well, you can get one           
from the file system.           
You've got a jpg in             
the file system.                
I hadn't told you how to        
access the file system, so      
you're not gonna be doing       
that. I'll show you later.      
You can also get it if you      
have a bag of bits that you     
got over the Internet. The      
data that has a bags of bits    
with jpg data in there.         
UIImage knows how to look in    
that bag of bits and            
figure out if it's an image.    
You can even use this           
global function,                
UIGraphicsBeginImageContext,    
and then draw arcs and          
lines, and it'll capture        
it as an image. So              
you can even draw a custom      
image if you want. So anyway,   
you do one of these things,     
and                             
now you have a UIImage in your  
hand that represents the image  
you wanna draw.                 
How do you draw it?             
Exactly the same as NS          
attributed string, you just     
use draw(at), which will draw   
the image with its upper-left   
corner at that point, but you   
also can do draw(in rect, and   
it'll scale the image           
to fit in that rect.            
So that's a cool way to scale   
your image up and down, and     
you can do drawAsPattern        
which will tally your image     
repeatedly, repeat you image    
to fill the rectangle.          
Super easy to draw              
images as well.                 
All right, let's talk about     
your bounds changing.           
I've got my draw rect. It draw  
beautifully, but now my bounds  
changed, and when will this     
happen? Well, number one way,   
your device got rotated.        
They were looking at you in     
portrait, they rotate you. Now  
you also went from this tall,   
thin view, now you're this      
wide, very short view, okay,    
your bounds have                
completely changed.             
You went from a width of maybe  
200 to a width of maybe 700,    
and from a height of maybe 3    
or 400 to a height of 150 or    
200, so that's a major change.  
You're gonna have to really     
redraw all of your stuff,       
usually. Unfortunately, that's  
not the default. In iOS,        
when you're bounds change like  
that, it does not redraw you,   
believe or not. It takes all    
your bits And squishes them.    
So looks absolutely             
terrible most of the time.      
To smashes a bit,               
squishes them down,             
stretches them out to           
fit your new bounds.            
Which you almost never want     
that. So how is that control?   
That's control with a var in    
UIView called contentMode.      
Okay, and the contentMode's     
just basically saying,          
what kind of content do I       
have? Do I have the kind of     
content that can be squished    
and scrunched like that, and    
still look good? Or do I have   
the kind of content where I     
have to be redrawn when         
my balance changes?             
So, the three different         
categories of contentModes.     
One is, keep my bits, okay,     
don't redraw me, but just move  
my bits, unscaled, to a new     
position, upper left, top,      
lower right, keep it in         
the center, whatever.           
This one not almost never get   
used. Then they're scaling      
the bits which is scaleToFill   
as the default where it just    
scrunches the bits to fit in    
the new space. It doesn't even  
respect the aspect ratio. But   
you could set the contentMode   
to scores the bit but keep the  
aspect ratio the same size so   
that a face doesn't go from,    
you know, an over as way to     
a tall over or whatever.        
But the one you guys probably   
are gonna want most of the      
time is ContentMode redraw.     
And what that means is,         
when my bounds change,          
call my draw Rect and           
let me draw myself again, and   
that's probably what you want.  
Could you draw rect knows       
what your bounds are and        
when it gets called, it can     
draw something appropriate for  
the bounds you read. So like    
in your homework, for example,  
well maybe your homework is     
not a great example because     
probably, the big views         
that are changing bound         
it's your subviews that you     
are gonna want to lay out,      
which I will talk about again.  
But if you did have a thing     
where you are drawing           
something in a view,            
like maybe we are doing our     
cards and concentration. And    
we always want them,            
to be a certain aspect ratio,   
whatever, we could redraw,      
in our draw Rect or whatever,   
it's probably not               
a great example.                
In fact, let's go on to         
the next example which is,      
what happens if I               
have subviews and               
my bounds change? Cuz this is   
gonna happen in your homework.  
You're gonna have some views,   
you're just gonna have          
a subview which is a lot of     
cards, your set cards. Because  
in assignment three, now        
there's no limit on the number  
of cards that can appear        
on screen, right?               
In assignment two, we limited   
to like 24 cards as the most.   
Now no limit, so you're         
always adding more cards. So,   
you're gonna have to use, put   
them as subviews of some view.  
You can't stack view anymore,   
in other words.                 
So what happens when            
your bounds change there?       
Well, when your bounds change,  
you're gonna get sent this      
message layoutSubviews.         
And that's an opportunity for   
you to go reset the frames by   
just changing the frame var on  
all of your subviews, okay.     
So, you're all,                 
if you have subviews,           
you're almost always gonna      
implement this method.          
And don't forget to call super  
to do it. Now, what's the one   
time when you're not gonna      
implement this method?          
Is if you have subviews and     
you have autolayout on those    
subviews, okay. If you have     
autolayout on your subviews,    
then the Autolayout constrains  
will determine where            
the new frames are, okay.       
So this would only be for       
views where you're              
not using autolayout.           
that might be true of           
your assignment three,          
whatever view contains your     
card, probably not gonna use    
autolayout. It will be          
almost impossible to write      
constraints that                
would work for                  
laying out an arbitrary number  
of cards in arbitrary bounds,   
okay. You're probably gonna     
wanna do that in code. Okay,    
so when your bounds change,     
you've got two different        
things to think about.          
If you have any subviews,       
layout subviews or autolayout.  
And if you draw something,      
then you've gotta think about   
your content mode on whether    
you wanna be asked to redraw.   
Okay, so that's it for          
the slides today,               
I'm gonna into demo here.       
The demo I'm gonna do is a      
playing card. So this is gonna  
be a new app, and it's just     
gonna draw a playing card,      
you know, like jack of clubs,   
six of hearts, whatever,        
it's gonna draw that card.      
We're gonna draw that custom,   
by ourselves. And today, all    
I am gonna do in the demo is    
the model of that MVC that      
draws the playing card, which   
is gonna be a playing card and  
a deck of playing cards.        
And the reason I'm gonna do     
that is I wanna show you enum.  
You haven't grab a chance       
to see me demo enum. So         
we're gonna use enums in our    
implementation of our model.    
On Wednesday, I'll continue     
with the drawing part of this   
demo or I'm gonna draw          
this playing card.              
And then I'll do some           
slides on multitouch and        
then we'll add some multitouch  
to the playing cards, swiping   
to go to the next card, we'll   
do tapping the flip the card    
over, that kind of stuff.       
Okay, your assignment two       
of course is due on             
Wednesday as you know.          
Assignment three will be        
assigned on Wednesday.          
It's just to make your set      
game custom cards, okay,        
drawn with a custom view,       
that's what assignment three    
is basically about. We don't    
have a Friday section again     
this week, unfortunately,       
due to some scheduling          
conflicts, but                  
next Friday we will and it'll   
be on source code management.   
Okay, let's go create           
a new app here.                 
Okay, so I'm just gonna go      
over here, use this same        
splash screen but I gonna say   
create a new Xcode project,     
this has nothing to do          
with concentration here.        
As always with                  
the single view app,            
I'm gonna call this             
app PlayingCard.                
That's what it does to          
show it's a PlayingCard.        
We're not doing any database,   
we're not doing testing yet.    
We're gonna put in the same     
place I put concentration,      
we're not doing source          
code control yet,               
although like I'm               
saying next Friday,             
we'll learn about that.         
Here's my project,              
now this time I'm gonna         
keep my xcassets,               
right, here's my xcassets       
where my AppIcon is here.       
I'm gonna keep that because     
I'm gonna use some images for   
the face cards. So you can      
see how to draw images there.   
But I'm not gonna use           
my launch screen or             
my app delegate here. So I'm    
just gonna put them again in    
supporting files. I just like   
to get them out of the way so   
they don't really kind          
of demand my attention.         
Now, before I even go here and  
build my UI for                 
my playing card thing, we're    
gonna go do our model first.    
So we're not gonna              
do any UI to start,             
we're gonna do model first. So  
how do we create model files?   
Remember, File > New > File,    
and we pick this one right      
here, Swift File which          
is a non-UI, right, a UI        
independent thing. And when we  
do that, we ask for the name,   
so let's first start by doing   
a playing card. Okay, now on    
my model, it's just gonna       
be a deck of playing cards.     
So these are gonna be UI        
independent representations     
of playing cards,               
a deck of that. So              
we'll start with the playing    
cards itself and                
then we'll do the deck.         
So here it is right here,       
import Foundation, I'm just     
gonna have it via struct,       
there's really no reason for    
it to be a reference type. And  
it's going to be                
a playing card. Now,            
a playing card is made of       
what? Well, it's got a suit,    
which I'm gonna have some type  
for that, and it's got a rank.  
Right, that's all there is in   
a playing card, suit and rank.  
So how are we gonna             
represent suit and rank?        
Well, of course, because I      
wanted to show you enum,        
l'm gonna do it with an enum.   
So, let's create an enum for    
the Suit. And then we're also   
gonna create another enum for   
the Rank. Now let's talk        
about how we would do this.     
Now, Suit is probably the       
world's simplest enum, right?   
It's the case, it could be      
spades, or it's hearts, or      
it's diamonds, or               
it's clubs, that's it.          
This is probably enough right   
here. That's really all         
we need to do for an enum. I'm  
gonna take this opportunity     
to teach you a little           
bit about enum that             
I didn't mention                
even in the slides.             
But it was in your homework     
reading, so hopefully you got   
this which is raw values. What  
are raw values in an enum?      
Well, it turns out that         
you can associate a fixed       
constant raw value for          
every one of your cases.        
Okay, now, Swift will even do   
some of this automatically.     
For example, if I make my raw   
value type which I specify by   
just saying, colon type, after  
enum, by making being int then  
it will automatically make      
this one's raw value be 0.      
And it's gonna make this        
one's raw value be 1, etc.      
Okay, 1, 2, 3, 4, 5.            
So, it just goes in order,      
the lexical order which         
appears in the file. You can    
also make your raw value        
be a string, for example.       
And if I do that, Swift will    
automatically make this one be  
spades, this one will be        
hearts, this will be diamonds.  
Another words, it makes the     
raw value be A string version   
of the case. Now, why would     
you ever want raw values?       
Well, to be honest, I think a   
lot of the raw values support   
backwards compatibility         
because in Objective-C enums    
were essentially ints, right?   
Zero, one, two, three, four,    
five. So raw values it's        
like raw value int. But         
you could imagine, it might be  
interesting if there is some    
piece of data that it makes     
sense to associate with all     
the cases. And again it has to  
be fixed, and constant, and     
unique. For all the cases but   
still you could imagine that.   
For example, I kinda saw        
that maybe this suit raw,       
this might be a good one. If I  
made the raw value be string,   
maybe having the Unicode        
character that represents       
the suit. Kind of be            
associated with every case,     
might be valuable. Now,         
how can you use raw value?      
Two ways, one, you can create   
a suit by providing the raw     
value. And it looks just like   
an initializer on suits,        
suit open parenthesis raw       
value, that's how you do it.    
And you give it like a heart    
symbol there, and it will give  
it back. Now that's a failable  
initializer cuz you might give  
it a string like x, that's not  
one of these four strings. And  
you can go the other            
way as well.                    
You can, if you have a suit,    
like suit.spades, you can say,  
what is the raw value? And      
you can get this string so      
that might be useful too.       
We don't really care about      
that in this demo but           
I just wanted to show you       
about this raw value business.  
All right, let's go down        
to Rank. Now, honestly,         
if I were doing Rank, it would  
look like this, case ace,       
case two, case three,           
all the way up to case jack,    
case queen, case king.          
This is what now,               
all the ones in between.        
That's what I would do.         
But I'm not gonna do it         
this way cuz I wanna            
show you associated data. This  
is mostly for demo purposes,    
I would probably just do        
it as these 13 things.          
That was probably the best      
representation for a rank. But  
instead, I'm gonna do it        
with associated data and so     
I'm gonna have case ace,        
then I'm also                   
gonna have a case face,         
which is a face card.           
And it's gonna have             
an associated value,            
which is a string, which is     
either J, Q, or K. So there's   
gonna be a face card that's     
either jack, queen or king.     
Terrible representation,        
at the very least this          
should be another enum,         
not a string which can be       
anything. It's kinda silly,     
but anyway. And then I'm also   
gonna have case numeric, okay,  
for 2, 3, 4, 5, 6, 7, 8, 9,     
10. And it's gonna have,        
of course, associated data      
int. Now, I could put in        
here like pips count, a pip     
by the way is one of these,     
a pip on a card is just one     
of these things. So a numeric   
card has 2 pips on it, 2 has 2  
pips, 3 has 3 pips and so on.   
So I could put pipsCount here   
as documentation. But you know  
what, you actually don't wanna  
do that if it's completely      
obvious what this would be.     
And if I had a numeric rank,    
it's completely obvious that    
this is the number, so I do     
not need that. Now, it's not    
very obvious what this is but   
as I already told you, this is  
a bad representation anyway.    
But I just wanna show you       
what it looks like to           
get the associated data out     
of here and use it, etc.        
For example, rank is an enum,   
it can have funcs,              
I could have funcs and vars on  
here. So I'm gonna have a var   
called order which is an int,   
which is gonna return the,      
which position the rank         
is in the order. So             
I'm gonna switch on myself and  
if I am an ace, I'm gonna       
return 1 cuz that's the first,  
that's card number 1,           
right? If I am a numeric,       
then I'm going to get my        
number of pips. And I'm gonna   
return the number of pips.      
Cuz if I'm an numeric card,     
then however many pips I have,  
that's my number.               
And then for face,              
I'm gonna say case .face,       
and I'm gonna, whoops,          
get the kind, Q or J, or K.     
Now, I'v got the kind,          
I guess I could say, I'm        
gonna go to the next line and   
say, if the kind equals J,      
then return 11. And             
then I guess I could go else    
if the kind. Okay, but I'm,     
this is getting terrible. This  
is gonna be ugly, awful code.   
But turns out there's a lot     
better way to do all this       
which is to go here and say.    
If it's face where I get        
the kind where kind equals J,   
then return 11.                 
So this stuff with switch is    
actually a pattern matching     
language, which you can go and  
learn about.                    
But one of the things           
it's able to do is where.       
Where it can kind of narrow     
this down a little bit.         
So now I could do that for      
all three here, the Q and       
the king, and return.           
That's why you can see          
why I use this terrible         
string representations, so      
I can show you where.           
Now, notice when I do this,     
I still get this complaint,     
switch must be exhaustive.      
And it's like, what?            
Look I do ace, I do numeric,    
I do face,                      
how come it's not exhaustive?   
Well, because                   
where makes it so               
these are not counting every    
possible combination of where.  
It could be, the kind could be  
something else. So, of course,  
I have to add here              
a default break, or             
actually I have to return       
something, so I'll return 0.    
This is also bad design. This   
probably wants to return nil,   
and this wants to be an         
optional. That would be better  
design, I'm not gonna do        
it that way. But just so        
you know, that's bad. I could   
also have static vars here,     
maybe I have a static var,      
which is all the ranks which    
returns an array of every       
single possible rank.           
And I'm gonna have to kind of   
build that up cuz I have all    
these weird data structure      
here. So I'll create something  
called allRanks which could     
be a type array of ranks. And   
let's start it out with and     
ace, notice here by the way     
that I have to type this        
side here. It can't really      
deduce this. If I took this     
away right here, let's get      
these other warnings off here,  
I'll return them allRanks.      
If I took this typing right     
here, this static typing away,  
I'm gonna get an error that     
it can't infer this type.       
And that's because there might  
be another enum that has        
a case of .ace.                 
So how does it know the,        
which array of enums this is?   
That's why it's saying type     
expression is ambiguous         
without more context. So        
I can add more context          
by putting that type.           
I could also say rank.ace,      
that would add more context.    
And now it knows it's           
an array of ranks. So           
now let's also do for pips in   
2...10, remember dot, dot,      
dot without the less than       
means including the 10. And     
now I can say,                  
allRanks.append, Rank.numeric   
with that pips. So now I've     
added all my numeric ones, and  
then maybe for the thing,       
face card ones I'll             
just say allRanks plus equals   
an array that has rank.face,    
where the kind is a J.          
And then I'll just copy and     
paste, copy, oops,              
paste, copy, paste and          
we'll do the Q and the king.    
By the way, if I do this,       
I only really need to put this  
Rank dot on the first one and   
it can infer the rest of them.  
Dots though means dots. So      
I don't need rank dot, because  
it figured out pretty quick     
this is an array of ranks.      
These are all ranks, so it      
works. I could do the same all  
thing up here by the way, too.  
I could have a static var all.  
I make it static because I'm    
getting all of them here.       
I'm not talking about           
a specific one so               
I want them all.                
So this would be,               
we'll do the same thing here.   
A rank of suit.spades,          
.hearts, .diamonds,             
and .clubs,                     
oops, hello .clubs. So          
this is kind of nice to have    
this static bar which gives me  
all the suits, all the ranks.   
That's gonna make it a lot      
easier actually to create our   
playing card deck so let's do   
that. So we've got this nice    
representation, not so          
nice, but somewhat nice,        
representation of a playing     
card. Let's go ahead and        
make a deck, so I'm gonna       
make a New File. A new thing    
here it's gonna be              
a PlayingCardDeck.              
Here it is, struct also         
no reason for not to be         
PlayingCardDeck. And, what do   
I wanna playing card deck.      
Well, of course I'm gonna       
need a var which is             
the cards in the deck.          
Right, so                       
I'm just gonna make that V      
an array of playing card,       
probably want this to           
be private set. Okay,           
where I control the cards       
because it's gonna be start up  
being a full deck. And then I   
probably want some function,    
like draw which grabs           
a PlayingCard out of there. So  
that's how you take a playing   
card out of the deck. So        
how would I implement drawing   
the card out of there? Well,    
I'm just gonna say,             
let's see what I remember,      
I think I used something from   
Concentration to do this.       
Check I did. Yeah, I did.       
Okay, so here,                  
I'm just gonna see              
if I have any cards.            
Then I'm going to return        
cards.remove at: hover many     
cards I have                    
.count.arc4random. So,          
I need to go over               
to Concentration.               
Here's concentration            
down at the bottom here.        
We have arc4random. So          
I'm just gonna grab that out    
of here. Put that in here, so   
I can use arc4random there,     
if I don't have any cards left  
then I'm gonna return nil, so   
I better make this draw our     
return an optional playing      
card. Okay, so                  
that way people can't add more  
cards to my deck I just         
start out with a full deck.     
Okay, I get start out           
with a full deck so             
I better have an init that      
does that, init is really easy  
to write given our nice         
plain card structure, sorry,    
this warning here, cannot use   
mutating member on immutable    
thing, everybody knows why      
that is. This is a struct,      
it's a value type, this         
mutated by removing a card,     
so we have to say this          
is a mutating mark,             
another good example            
doing that. All right, so       
here I'm just gonna go          
through all my suits for        
suit in Suit.all, and for       
rank in Rank.all, okay,         
then now all these alls that    
we did, but of course look      
where I put suit, if you look   
at PlayingCard over here, I     
put suit inside Playingcards.   
See I declared it inside,       
so Swift allows you to nest     
types, put types in other       
side. Which makes perfect       
sense here, because Suit        
only makes sense in the         
context of the PlayingCards,    
it just makes perfect sense.    
But it does change the name of  
the Suit,                       
it's no longer called suit,     
it's called PlayingCard.Suit.   
Playing Card.Suit and           
this is PlayingCard.Rank,       
PlayingCard.Rank.               
So nesting just changes         
the names of things and         
the accessibility               
can do private and              
stuff like that you might not   
be able to see it. So now that  
I have that I can just have my  
cards append a playing card,    
now PlayingCard since it is     
a struct is going to get this   
automatic initializer,          
you see it right there, so      
I'll double click on            
this to get that. And           
the Suit is just gonna be the   
Suit that I'm for in-ing and    
the rank is the rank I'm for    
in-ing.                         
So now you can also see         
the nice context here and       
the nice syntax of for          
in when this is an array.       
These are arrays.               
We're just going through each   
element of the array, right.    
Remember that these             
are arrays right here? See,     
this is an array for Suits.     
This is an array that we made   
for Ranks. All right. So        
that's it. Now, last thing I'm  
gonna do here is just print     
out some cards in my deck to    
make sure it's working. Kind    
of a cool place to put testing  
code is back in your View       
Controller. Okay, if you look   
at your View Controller you     
got this two frame methods.     
I'm gonna get rid of that one.  
But I'm gonna keep this one     
which was mentioned in your     
homework. This is, viewDidLoad  
is a great place to like        
initialize your                 
View Controller. And            
also just put like debugging    
code, checking things out,      
things like that. So,           
here I could do for example,    
let's just print out 10 random  
cards. I'm gonna say for        
under bar, cuz I really         
didn't care about the index,    
in 1...10 cuz I want 10 cards.  
I'm just going to let card      
equal a playing card deck, so   
I need a playing card deck,     
var deck = PlayingCardDeck.     
So I'm just                     
gonna let the card              
= deck.draw.                    
Now, this is going to be        
an optional playing card right  
here, right? Optional playing   
card because the deck might be  
empty, so let's go and say if   
let, although I probably could  
put exclamation point cuz       
I'm only grabbing 10 cards.     
I know there's 52 cards in      
a deck, but we'll do if. And    
now I'm just gonna print        
this card out. And              
I can print a card by using     
this backslash parenthesis.     
Swift knows how to print        
out things that have,           
we'll see what it tries         
to print out when we,           
when we do this here. So let's  
try that and see what happens.  
So I have no UI's, so           
this could be a blank UI but    
it's gonna print this stuff     
out on my console so I really   
only need to just look at       
my console here, Right, so      
there's my thing here, so       
here it is printing it out,and  
it prints out 10 random cards,  
kind, ugly looking right here,  
it prints out all the vars and  
etc. One thing that's really    
cool that I don't have time     
to show unfortunately,          
cuz we've already gone over     
but I'll just mention it,       
is that you can make it so      
that something prints out       
really nice when it's           
got that parenthesis,           
backslash parenthesis, by       
making it implement the custom  
string convertible protocol.    
So if we made playing card      
implement custom                
string protocol,                
the only thing that's in        
that if we do fix it,           
we'll see what it is,           
is this var description and     
you can return, like here       
I could return for example      
a combination of the Rank and   
the Suit, and then I can go     
make custom string convertible  
for Rank and Suit down here.    
Comma CustomStringConvertible.  
Implement the description in    
there as well. Okay,            
which I'm trying to do, so      
we will go here, we will put    
description, we will go here,   
we will put the description,    
and we would implement these    
two vars, and then when we      
print out, it would print this  
nice string with two            
nice strings with that.         
Now, we wouldn't get all that   
really verbose printing out.    
So CustomStringConvertible is   
a nice protocol to implement    
if you want things to print     
nice in the console. Okay, so   
that's it.                      
I will see you on Wednesday.    
We will dive into doing         
the M or the V and C part,      
which is to draw                
a playing card.                 
And we'll learn all of          
that custom views and           
all that, I know there is       
more to touch after that.       
See you then.                   
>> For                          
more, please visit              
us at stanford.edu.             
