Okay, let's go and start recording.
Let's get this started. Okay.
Okay. Good morning.
Let's get started here.
still arranging my windows here a little bit.
Let's make this a little smaller.
So, up for today we're going to talk about tutorial three.
Before we do that just a little bit of administrative stuff.
If you have.
So there is an assignment first assignment coming up I'm probably gonna give you a couple more days for it. And because I haven't put it out yet but I should have it out I think by the end of the day by tomorrow.
The, the topic of assignment one will be the material in tutorials one into, so it shouldn't be too bad but if you look at the code for tutorial.
Two there is some things to pay attention to. So, that will that will be asking about.
It will be short answer. So, in a sense, and what you're going to how you're going to speak your answers is going to be a text file I'll, you know, I'll put it all in the instructions.
And I will explain more on Friday. So, but you'll have the questions I think by tomorrow.
I got sucked into working on my tutorial three which is what we're going to spend time talking about today.
Before I talk about the code and things, let me just show you what they are.
So, I actually have two versions of this right here.
The one on the right is actually the one for your tutorial, and the way it works is very simple you have this circle you have this box, you drag the circle into the box and when you get it into the center of the circle, it says success.
Now, why is it not actually my chat window sorry I just.
There we go.
Right.
But so that's so that's what it's, you know, that's been here and this program here is drag demos this drag demo to drag demo I changed from dashes to just think because it looks stupid Lang drag dash demo to that.
But this is the one from last year.
And it functions, essentially the same way. Now notice I'm not running this in the iOS simulator, I'm running this as a Mac was application, because I wanted to illustrate something.
So now I want to show you is, when I change the size of the window for last year's code.
It doesn't change everything stays the same. It's not scaling with the interface.
But
this one does.
So part. So what I'm going to talk about today. First, is how this code works. And then also how I had to change it in order to get this, because one of the big challenges in doing mobile application development and really increasingly any sort of gooey
development is you can't assume a fixed screen size or a fixed resolution, so old style interfaces, you can just park code things, so you get the positions and stuff there and you get signed that would work fine on a given set of screen dimensions.
But now we really want our interfaces to adapt to lots of different screens.
And so we have to do these things so in Swift you are you certainly can do fixed layout as you'll see, but it's also very possible to more scalable layout.
But it's a little trickier. And part of the trickiness is involves understanding how swift UI works.
And, and so we're going to, this is what we're talking about today.
Roshi wants to be loud. Okay, we'll let him out. Okay Roshi you can leave and go on
can stick around for all the class.
So first off, just quick question on Wait, I'm going to do a poll.
Let's create a poll here, or create a poll.
We'll call this Easy, easy.
God wants to pull.
Curious which all.
Okay, I'll give you guys a little more time to answer the poll and then
we can discuss that. Okay, so
I'll give it.
I'll give it a minute before I stopped, I close the poll here. The reason why I'm asking is because things are going to get a bit more difficult. Well, some ways some ways.
Let's look through the code first of last year's thing so the poll here.
Okay, so you all can see kind of a spread a third of you said was moderately difficult few of you said it's very difficult.
So he said not easy but not difficult. And then, yeah, so.
So what drag demo as you saw what what drag demo is is just this you draw a circle you draw square, you draw a thing at the top, and then you have, and then you move it here and when it's there you change this to success.
So, the probably the most interesting thing here is we have to be able to drag something around drag a circle.
And we have to be able to know when the circle is inside the square.
Okay so
oh sorry I missed so the comments here.
There's a circle eventually get bigger than the box, know the circle is never bigger than the box when every scale it.
Okay, so
it's easy to count with modifications but hard to understand all the code Well, yeah, you should endeavor to understand all the code yeah so that it turns well you'll see exactly how the how the sizes are done here but first let's look at Dr demo.
So, the original drag demo is ok so first, the inputs with UI.
So we define the box location to be this fixed position. So a CG point so this is just a point type that's using on iOS. And so it's going to be the XMY locations 214 so you see here it's hard coded the position of the box.
And this is our main content view, we have a state variable called location.
Okay, why can't I look at this here.
This is the old code. There's the old cup. So we have a state variable that's the location, and this again has starts off at a fixed point where it's going to be.
This is the location of the circle.
And then we have our view we have a V stack. So this is a vertical stack one below the other, you know, top to bottom, we have a success message.
The success message is a separate view. So this is, this is one new thing here, we are decomposing a view into multiple views. we can have one view another view another view.
You know, I think we did that last time so but but so yeah so we have another view here yeah and so we connected the success for you will see that a second and then we have a z stacks that means one in front of the other.
And so the idea is that the rectangle and the circle or kind of on different planes we want the circle to be on top of the rectangle course make the rectangle square because it's, you know, fit you know same fixed width and height least give the color
circle view is because we need to share it between success message and movable circles since both of them need information, you'd access to the same state, we put it in the containing view
as moving circle built in function now.
So movable circle is.
So we have two views here. What is mutable circle here, and the other is success mesh so these are separate custom views. And that's basically how you makes with you I know interfaces, is you make many views and you put your usable parts in here now we're
not really reusing these things but we're also just separating out you'll see there's actually lots of reasons to make these separate views. So now the movable circle has two separate has a binding.
So this connects to this state variable here, and has its own private state of is it dragging, or is this basically being moved. And so here what we do is we we say we return circle so we're returning this view we actually don't need that return I can
I can get rid of that.
Again this is old code so.
But we do a film of the color blue. So we're going to circle in a blue circle we give it a frame your fixed height in a position which is location which is shared from here.
And then we have this thing called gesture, so I'll explain this later, but this is how we make it drag.
Because basically the way we do the drag is position location is a variable that can change, and this drag gesture changes the location and simply by changing this location, we get an animated circle.
So, and then success message is just has an if statement, and that either says, either so text, either success or shows this dragon circle a box and it decides which one it does based on the comparing the location with box location, and just saying, are
those to close enough.
And then we have our preview thing.
So, that's kind of the base, we'll talk about how this drag gesture and stuff works, but now you have an idea of the basic structure here.
Now, in the, in, you know, the one we're talking about this year.
It's basically the same idea.
We have our success message, we have rz stack of our centered box are movable circle.
and we ever text.
But we have more state first of all we're computing, all these values were computing all these values from this thing called geometry reader.
And,
you know, and we know we can do a lot of calculations based on those numbers and that's how we figure out where the box should be, but it's really just instead of a hard coded thing we're dynamically figuring out using the numbers that geometry or does.
I'll explain what it's doing it a little bit.
Then, otherwise the center box is basically the same thing.
I'm excited. I pulled it out into a new view, rather than just having a wreck, you know, having it be there and movable circle is essentially identical as before, except there's another little thing here, and then success messages essentially the same
except I made it a title font, instead of that.
So,
so okay so the minus 100 minus so let's.
So there's a lot of things to unpack in this code and I'm going to talk about the differences but I just wanted to first show you that the codes different but it's not hugely different, but I think it makes sense to first try to understand the simpler
one.
Before we start talking about the more complicated version,
and in particular the thing I want to, let's talk about what this drag gesture it so you can associate essentially a dry, a gesture, with anything in Swift, basically with any view.
So you can make any view respond to gestures. But when we say respond to gestures, it just means, it gets an event. And so one of the gestures that you can get is you're pushing down on an item and then moving it that's considered a drag gesture so we're
saying okay here we want a gesture we want a drag gesture. And so when the drag gesture happens basically as the drag gesture happens we're having this on changed things so we can also say on ended so say when someone let's go with their finger but this
is just your dragon someone from one place the other was saying, as the drag is happening on change. We have a little function.
Now this is a closure and in that comes the value of, you know, what has no what's the status of the drag.
And so that value, know that value location says, Where is the person's finger right now. And so here we go, self dot location is just saying this location inside of the struct because we have to say self dot location, basically to make sure we refer
to outside disclosure, but I think this might work with have it just location.
I have to check. But self that location is referring to inside this object and value location is the value we get here so notice that moving things having it follow your finger it's almost trivial, we're just really saying, Oh the finger move, oh let's
update the location.
Yes So Dr gesture is part of swift UI.
Exactly drag gestures products with you I, and in fact, you're going to find
because of how swift UI is constructed.
You really do have to rely on the built in things and if you start trying to create your own code to try to follow a fingers on you find that it just, you have to do really crazy stuff.
It just, yeah.
So, So, so binding variables. So the binding variable here again we talked about this last time but that's just bindings.
So,
so, So, so yeah.
So, we have.
So binding variables are access to one and that so that's what we have here we're connecting these two views. Ok so now I'm going to the actual, like go back to about so you connecting these two views, we have a bit this is our main view content view
this is really you could say, our screen.
And the.
And then when we want to connect, we have some state associated with the screen that this what the view represents the whole screen, which is the location of the circle.
And we need to the reason now really logically you think the location of the circle should be in the circle.
but the circle is being included inside of this view, and state, you can't go by. And then, so as a success message so we can have success message and movable circle directly share data, because they're both separate views one doesn't include the other.
The only way we have data shared between them is have the containing view, have some shared data so we have a state variable here and then we have a binding to it in movable circle.
And in success message that way they both are accessing the same data. They're both referring to the same variable which is location in the main content view.
So, this.
So I was happy to review because I'm sure other people know, I'm happy to repeat myself so we did talk about that last time but this is in a new look and new contacts.
I'm thinking like the. So when you see this dollar sign, this is basically saying, I mean referring to a bike, I'm basically passing a reference to a state variable to a view.
But we can, we don't have to forgive you for binding variable does the name of the variable need to be the same as a state variable.
No.
It does not and in fact, if you look here, we do some things a bit differently so here we ever main content view.
I'll explain geometry, watch I took place when geometry or real quick, geometry reader, just.
Oh that's really I think its parent child.
I think its parent child.
So, so what I'm saying here is that when you.
So when you create a view. You make a V so I have a view here.
And I'm making a. So, so I've got this view here content view geometry reader is another view that's inside the main content view, it really it doesn't do anything except figure out the dimensions that were given to it, and it passed those in with the
input variable here we're calling it geometry.
And so the V stack here which is a view. Basically, if you want to know how much space does the V stack have to work with what is dimensions of the box.
That's what geometry reader tells us, and then where success message goes is based on the baton the bounds, that are given to it by the stock.
You know the stock says okay you get this portion, and then z stock you get this portion, and then tax you get this portion, and then z stock says okay here center box this is where you're going and mobile circle.
this is where you're going. So, the child views, always basically asked the parents, where am I supposed to go. Where should I draw myself. So, this starts first with you have us view for the whole screen and then each of the sub ones fit into pieces
there.
So.
And so what we're wanting to do in order to figure out how all those little parts are going to fit in, in these different views, we have to pass data up and pass data down in order, because of course, we're one view should be positioned is potentially
based on where another view is.
And if you want to do this dynamically, you really need to know what the dimensions are so that's what this geometry reader does and then I've added all this code to basically do calculations on it.
And so, and so now you know location and box location, they're all become variables. Notice that.
So notice location is a reference to circle location
and box locations here. I really, I should probably change my success message so this is my, you know, based on the old coaching see location here in box location, they should really be circle location.
But, you know, so but the names, you know, here are different.
But one thing to keep in mind is notice I'm sometimes using dollars signs, and sometimes I'm not.
Yeah, the stock is just an overlapping stuff on top of the other. It's just telling what goes on top what goes above and what goes under, that's all of these packets, you know, you say V stack is vertical h doc is horizontal.
Second thing z stack is, how do you layer thing because, of course, what's on top of another will include the other.
So the Z stack what determines whether when you draw a circle on, on each one of you allow a circle to be drawn on top of the square, you have to specify which is on top which is below it.
But notice with this, locate location here in size. Here we're not specifying a.
There's no dollar sign here.
And here there is $1 sign. And so, why do we sometimes have dollar signs and sometimes don't have dollar signs.
Yes, so I printing see stock willing to put one view on top of each other. Exactly, Yes, exactly what we do with a Z stack.
But if you look at the dollar. Look at these variables here. so here this is a state variable.
And then we have all these little other values.
These are more bindings than variables what that means. So, and this is an important thing that I'll explain but knows if we say state.
We're going to have to use $1.
And if we don't use state, we can just use the reference the name. And so you'll notice here with this centered box. The box doesn't move. So I don't have to worry about giving it a state variable because it's never going to change.
So I can make it fixed.
And so here.
It takes a location and Assize location in size are passed in.
From here, low box location and box size is the location and size here. So those are here but notice.
Those are fixed values.
So, you pass things by the normal way if you pass things to a sub you what you're actually doing is you're passing things by value so like a normal function, you're sending things to the function.
Do you all know pass up call by value and call by reference.
Is this terminology, you will know.
Okay, voice.
So some of its own view or no so you yes okay so.
call Bye bye.
Bye bye.
So that's really the idea here is that call by value. You're, you're giving it a value and saying, Here you go. Do what is what you want.
The function gets a variable it can do whatever it wants with it, but the color will never see the changes, versus a call by reference.
You know if you change if the, if the function changes those values, then you have that, then the caller will see this.
So, in see you know all functions are called by value, but you can pass in a pointer to call by reference semantics.
So in Python.
So I, I'm pretty sure about this normally whenever you pass in a dictionary or an object.
If you pass into an object or dictionary you pass it to a function and it changes it. The color will see it, but if you just pass in a number or a string that won't get changed.
This sort of idea, this call by reference call by value is really important. It all comes in, you know.
really.
So, really, when we call a function.
Are we just gonna have to care about the return value we don't have to care about what it does inside or do we have to worry about what it's doing to the data we sent it.
me a lot of times we, you know,
another way of talking about this is, is data, Will.
Will the data be mutated. Will it be changed or is it immutable IE is a constant.
There's a real trend.
So, you traditional programming languages are very much based on this idea of mutable state like you pass this around this, this one function can you take some data structure and no one can change the data structure and, and who knows what state it's
in.
So sweet things with you I is really cool because you're creating interfaces, using immutable data.
And this has lots of weird little consequences.
And so that means when you call things, so
you know, I said immutable data but then I said state is mutable data we will notice that's the exception, you have to have some will say.
So,
this mutable versus immutable data, it may seem very abstract.
But it's really important and really influences how you do things in Swift, and
I'll show you some code things and then I want to step back a little bit and talk in general about how you do graphical user interfaces and how that and how that connects here so first off.
Notice, So I say my interactive so I'm in during the week switch to drag demo to.
So, here in drag demo to I.
You might ask why did I.
Why did I do, you know, why did I just do all these things last year, why did I do this, frankly, because I was struggling with this mutable versus immutable data, because there's some weird things here that took it took me some work to get my head around
and think I've got it here but it's like really simple stuff that.
So like I have a thing called like circle location here, this point here, so it's a it's a state. It's a variable, it's there. So, the obvious thing to do here.
The only obvious thing to do here is just to say that circle
patient is equal to.
CG point x colon.
Well, I'll just do this x colon. No, 100 so I'm not even I'm not even doing the proper value but like let me use this geometry value here to set this.
Let's see feel let me do that.
Notice this error.
This is the thing that all that discussion was talking about is trying to explain.
I put this circle location here, I have a state variable right there.
I'm just assigning to it, it's a variable right, I should be able to assign to a year, and I did this assignment here.
And this will work.
And you'll get this really annoying error, where it says type.
No, no thing here, cannot conform to view.
So, so in order this single location is mutable.
But state but swift UI is designed around immutability so state is this weird thing that you have to handle very carefully. And my question to you now is, why can't I just do this assignment here.
Why does this break
thoughts.
Circle location chain. Yeah. No, no, no, this is not a syntax issue. I do not have a syntax error here. I you know side that's a good that's a good guess.
There is no way basically to write this.
No, it's not because line 12 to 16 here, we're started buying the bus. Now notice these things are Lex.
Never let creates a variable
that creates an immutable binding between a name and a value. So when you have a let in your code.
This let means that this box location is this.
The meaning of box location will never change.
And, in fact, it is based on, like, basically, if I, you can go back and like well how do I know what box location as well mock location is based on WMHIOWHW and he is based on this.
And how do I know what geometry is as the input. So given this value that comes in.
Start location box location stuff are have a fixed relationship to geometry, it can never be changed.
So, so this is all well and dandy. This is fine. And essentially, I'm not violating, so.
So,
So, assignment two variables are not allowed.
So does binding also make it immutable binding. So, is a binding makes a mutable binding to a variable.
So, it's a reference to, you know, it's a reference to an existing. So you can see that binding is immutable but what you get from the binding isn't because it's a binding to a state variable.
So, this you know this circle location is a state variable. So when we do this binding here, location in moveable circle is immutable, in the sense of, it's an immutable binding because it always what this refers to it will always refer to circle location,
I can't have it refer to anything else but circle location, its value can change. So it's an immutable binding to a mutable value.
So, this, this may take some notes know some your head gear up but let's give you another perspective.
I've been using this terminology a bit. What is a domain specific language.
Does anyone know what a domain specific languages have you ever heard of that concept.
So, domain specific language is a sign that's used a lot in computer science.
So, the idea of a domain specific language is it's a language, designed to solve specific kinds of problems.
So problems you take in a given domain.
So any.
You can have.
When you make a domain specific language you can make it have arbitrary syntax semantics, whatever it is for describing your problem.
So for example, if I wanted to create
know if I if I wanted to create a solution for
books try to give a good one. Okay. Oh for.
What's a word to create, I want to make a robot that puts groceries on a shelf, you know put grocery items on shelves.
I can't spell today.
So say I want to create solutions to automatically putting grocery items on shelves.
So let's say I wanted to, you know.
So domain specific language they involve assembly language, none none.
Even implement them and whatever.
So, so let's say you defined in your finding an, you know, API custom API's.
This is a bigger topic than I want to get into.
Um,
yeah I think I've gone down a rabbit hole here.
It's worth looking up domain specific languages and reading up on them, but for now let's just say.
yes you me and custom as well.
So I'm seeing some API's API's application programming interfaces
are kind of a poor man's domain specific language.
So when I say, oh so I talking about creating a language, we have created a language because if you look at here.
This is, I have a variable here.
I'm doing an assignment to a variable and assignment to a variable in a normal Swift is perfectly reasonable.
But here, this generates a syntax error.
So that's what I'm saying is, this is not Swift. This is swift UI, which is a separate language, which mostly looks like Swift,
but is got these weird constraints.
And the reason it has these constraints, is because it enables it to do what it does,
which I need to explain.
So,
what I, what do I mean here now why can't I do this well let's talk about what.
we make a graphical user interface of any kind. What are we actually doing.
So we have input devices programs get the input.
And then we have.
Okay.
So
does this part makes sense so far. When we make a graphical user interface. There's fundamentally a frame buffer, the input, and those are code that sits in between.
So.
So,
yeah, input process output Right, so the classic way we do this for the gooey is an event driven system so you have a user generate some sort of event or code processes the event, and update the screen.
And whatever internal data structures you have. And then the code waits for
more input.
So if you want to do all the things while waiting for input.
We have to do it in parallel, or we do it in small chunks so we're always ready to handle user input because of course if you don't handle the user input in a timely fashion.
So if you don't, you know, respond. If you're not ready to respond to the user when they do something, you get input lag and, you know, unresponsive interfaces.
You've all experienced this.
So, this is the mental Molly how how a GUI application should work.
What's going on with swift UI.
we're not actually doing this.
This is not event driven code.
We do not, this is not a view is nothing but where's our, you know, what we have is we always think describing the screen.
And then, the only thing that is that all close to an input.
You know thing is this drag gesture on changed.
And the only thing it does is it updates one variable, it doesn't update the screen.
So,
so yeah so the dragon so so it's a.
So the way it maps onto it is.
So, with views, you're describing what the entire screen looks like. And you're doing that screen layout as a function of some data.
And that data, either is going to be constant, for the purposes of view or it's going to be variable. Now, there's some little bit of variability and things but it's either be constant over but if it's variable has to be put into a state variable, so
that.
swift UI is essentially you think every time the state variable changes. Swift UI updates the entire screen using all of us evaluating all of it and you go like that could be crazy and efficient if you're doing it all the time.
When you thinking, like, as I am.
No, go back here, as I am dragging this, it is basically running all the code, all the views.
And I'm getting pretty smooth animation, because with you is clever and they can do it efficiently.
But, you know, but I'm not that so my animations kind of a funny thing. It's just saying, Oh the views changes I mean you can see how fast it's updating because every, every little movement of the animation is just me redrawing the entire screen is sense,
or at least logically redrawing the entire screen but it's not flickering, mostly because it's actually very efficient and how it does it's got lots of tricks under the hood.
So when I saw wouldn't be counterintuitive. What do you mean,
It's In fact, it's, it's potentially very.
That's not how we used to do it, because it would have been very inefficient.
And in fact, when you ever you see interfaces flickering because they're redrawing all you go like oh that's a horribly built thing.
But if you by doing it this way.
You make the code so much simpler.
And we will see this later in the semester.
So
why is a circle so why is a circle being cut off sometimes.
I'm not I'm not sure if only this, you know, why can't it just also it's doing a lot of blending of the image, this is all happening underneath, it's doing.
It's doing a lot of stuff underneath.
But the idea here is, we just have a domain specific language to describe what the screen is looking like. That is what we are working with here is we just have we're working with this domain specific language that describes what the screen looks like.
and we tell it what to do.
And
by.
It leads to weird things like, I can't set a variable. So instead of setting this variable, what I have, you'll notice when you look at this code. It's very,
That's how I determine the location, I calculated where the box location is calculated the box size, calculating the size of the circle and everything relative to these things, and I passed them in.
And so, in the context of the center box and Google circle. It's immutable.
Of course the geometry of the screen could change that's what happens when I drag it, but again it's redrawing all the views so while.
The views are being the views themselves, need to be immutable they can't mess with state as they are being drawn, because it would be it would change how the views are doing it.
Yeah, so.
Yeah, so every time we drive does it location, does it add the location to a queue of locations, no it does not add it to a queue of locations at all.
That's what's really cool it's not, there's no queue here. It really is what it's happening so when you do this drag update it's saying like, as the drag happens as you're moving the finger, what happens is this function on change is being constantly
called as your finger moves it comes as it changes like as the porters go it's like, this is get call so this can get called really fast. And as this keeps getting called.
It keeps updating.
You know the value of self location which is this finding which were fear, which then goes all the way up to here, the circle location that's constantly getting updated.
And so when all the views get updated the position of the circle happens but while the views are being evaluated circle location can be considered a constant.
So these things are being run really fast.
And that's how you can do animation with them simply by changing the location of the circle I don't have to think about, you know, how did an animation is this really cool thing that you just get as a byproduct of how swift UI is constructed.
So,
so there is no queue of locations. This is literally just updating this value, it's just that, oh this values been updated. Oh, I better redraw the entire screen, and it does, and so doing it draws a circle in a new location.
Under the hood, it's not really doing guys doing so much smarter, but logically that's what's happening.
So, don't mess. So what this means is is.
So, so this is so that's the key. That's why you can't do things here because essentially you think of the view code is just being run constantly over and over and over again, and it better be producing the same values all the time.
And that's how it knows that the you know the screen has a stable state.
Like, if I put up, like if I did something like me I could put circle location, and I could just start implementing it. That means each time I ran this, it would give a different value.
And that would be bad.
So instead, we want it to be constant here and so it's only changed in response to events.
Okay, So, I've been talking for a long time.
So I think now, I will, I will stop the recording here.
And I will stick around to give you all feedback on tutorial to you check you off for tutorial too if you haven't been checked off already. otherwise I can do check offs are tutorial three if you get it done really fast.
Otherwise I will answer questions about tutorial three.
And now make breakout room so you all can chat about it separately.
Make sure your question real quick.