Okay.
Good morning everyone.
I've just started a little poll here, too.
I was just curious what people's computer setup was. And the reason I'm asking is because I just got a 32 inch monitor. This is the biggest monitor I've ever had.
It's 2560 by something but actually have to run at night. I had to run in 10 ATP for right now on the Old mac but my PC laptop which I will switch too soon for doing Android stuff that can run it for resolution so that.
But, yeah, 32 inches. Yeah, it's kind of big. I'm kind of like, Yeah, I don't know so that's why you're kind of seeing the camera from a slightly higher angle because that's the top of the monitor.
So, let's end the poll let's see how.
Okay.
Okay, there's a couple of you have participated, do the pole.
So, yeah, it looks like, okay, almost half of you're using a laptop with an external screen keyboard which is actually my normal setup.
And then, 16% laptop.
Right systems that desktop 32% laptop so once it has other.
I'm kind of curious what your other setup is.
If you've answered other.
You, you have more than one machine or something or.
No one responded yeah like I assume you mean for coding and watching the lecture so I watched the lectures on my Windows desktop and then just code on my Mac OS and then when I need to demo it, I just put up zoom there.it, so you have multiple computers,
got i doing switching between the two. Okay, cool.
Definitely worth paying attention to your ergonomics. Most of you are young, so it doesn't matter as much for a lot of you but trust me, it's worthwhile.
I think in my while I was in grad school I started having typing issues.
My hand started hurting and, and then I, I end up switching to divorce, and I was.
My hands started hurting and, and then I, I end up switching to divorce, and I was, um, it took about a month or so for me to be comfortable with it and I was otherwise, you know, I was otherwise sick so it wasn't so much of a problem in terms of productivity.
But yeah, it's really weird when you switch to me that that's how I dealt with my were kind of stressed off and that broke a lot of habits and I also remap some things I wasn't doing bad things my hands and I haven't really had problems since, so
we're thinking about anyway right now just remind you all were at February 4.
We have two more weeks before.
After this we have two more weeks before the break, and after the break is the midterm and midterm and exam midterm exam and you know review session.
The US, we're at, we're talking about tutorial for doing that today next week we'll do tutorial five tutorial five, we've now at this point covered it after today's lecture have covered everything I want to cover on swift UI and will be switching modes
tutorial five will be on UI kit and swift and then afterwards tutorial six on we will be talking about Android.
So tutorial five and six
will be yet we're kind of in the switching gears part.
Mostly the assignment to is basically going to be mostly on these tutorials will not be as much on this you'll see how it does actually a lot of concepts on here enough but I'll try put a little bit of tutorial five in there on the, on the second assignment
that you so you can have that for the midterm exam.
And the assignment three, I don't want. Ideally, you should be done with it. If you're not done with it yet you still have till the fish, you know, the 15th to finish it up, And then you have a weekend to the break.
To finish assignment too so you have that time if you need it but I would suggest you get moving if you can.
On the second assignment will we be coding anything no more than on the first assignment.
Soon, so I do have some things here.
You know, this is a bit of code right here on assignment one.
How could you say the analysis so.
So really for this assignment.
I should make sure.
Let's make that clear if you all didn't realize that if you have if you actually submitted it and didn't realize this.
Okay, so this is realized.
But.
okay,
rest them.
Yeah. The rest are really coating changes, but the last two Ark
was this one too.
Okay.
So yeah, so you should have been coding on assignment one, and there will be similar things. Now, I'm not going to have you write lots of code in this class.
And the reason why I'm not having you write lots of code is very simple. I've found that I can get you all to write code to trick is for you to write code that you understand.
So, so that's my focus is more I'd rather have you focus on smaller amounts of code that you understand what that's doing as opposed to large amounts of code and you sort of gathered from online sources and put it all together and got it to work but really
don't know what it's doing.
Okay so, so that's kind of logistics. Today I want to talk more about. So we talked about part of tutorial, unless there's any questions about the assignment.
Alyssa Alyssa a question about the assignment I'm going to go on to continue talking about tutorial for because there are several aspects of it we haven't discussed.
So, In tutorial for
this sort of thing. The only reason you really need this is I need it because my Mac is actually running mac os 11, I was thinking of trying to upgrade to 12 but it might break because this is so old, it's really not even supposed to be running.
Big sir but I think I'll try that, after.
Probably after I've done with your friends during the break.
And so I've added in these decorators basically because this just make sure the code doesn't try compiling on on my Mac I can't get it to run there.
So all this one that in the background.
In terms of parts of this so we've.
So what do we have here we have a V stack with a menu.
We have a menu here.
Okay, up, I, by the way, I'm fine for you all to talk to chat about things but if you're gonna have stuff that I don't need to read. Can you do it on teams.
Because otherwise I'm kind of like, basically it's like a conversation the middle of lunch o'clock. Okay, I can talk about your Mac Mini but yeah so sorry that's fine but site com It's fine, but yeah.
Anyway, um, so what do you have here we have a V stack here and we have a menu and we have buttons and stuff this we've all seen in response to the buttons we have an action the actions are closures and the closures just set a variable, and then call
reset state.
And so that, that reset status right here it's just a little function here. And notice the function is is part of the struct. It's actually a property of the struck content view and the.
Anyone know why it's a prop cry just declare this outside of it and just put it over here online 14. Would that work.
If I move this function.
What do y'all think.
Okay, let's do this. Exactly. No, because the variables are in scope. Exactly. Because look at the because look at this referring to move final amount an angle.
Those are all parts of the struct.
And so if we moved outside that would not be in scope and you wouldn't be able to modify them. So that's why we have often nested functions and declaring these things so they have access to the appropriate variables.
You can pass those in his arguments though.
Yes and no. Um, yes, in art. Well, that's true. Actually, that's true. That's well.
So if you would pass them in normal. Normally they will be passed by value.
So you just said a copy and what you have to do is pass by reference, those variables, and we have really talked about that here. And in fact, all of the functions that we've.
Yeah.
I mean you and they're private so you don't have a, you can't directly access like if you have access to the contract you could pass it a reference to it but we haven't actually talked about how to pass in references.
I'm sure you can do that in some way. Yeah, I know you could do that some way, basically, you probably have to use a classroom.
Anyway, just, it's a pain.
So that's why we. That's why we nest these things.
Because remember, like, how do we access in this different structure we have to do this whole thing of passing it in and using this weird dollar syntax and this is Pat passing a reference in trying to remember how swift passes references.
It's not, this
stuff. I'll check that up.
But you have cuz you know. So we have these views menus of view inside the menu view we have these buttons and then we have active image.
An active images connected here by the state variables their state over here, and their binding variables here. And then, of course, the real work of things.
Is this because here we have our treat our guests the geometry of the view. Basically this is everything on the screen.
Except for the other stuff on the screen. So what this does not include the menu because the menu is already taken it's portion. So here.
This is actually giving you everything that's the whole screen, except for the menu part
of question is what is the private key word do here. So, I'll tell you what the notice the private here. These are private here. These are not private.
So in particular, if you try declaring a private binding variable as private. It won't work. Because, in fact, they're not private they have to be accessed from outside of it, which is exactly what's happening here.
So, mean it's kind of weird that in a sense binding, isn't this going out it's more the other one coming in. And so these have to be public so that the others, you know, they can be access inward by the state variable.
I'm not quite sure exactly how this works under the hood because swift does crazy things with this type system to make this stuff work.
It's, it's actually, there's actually an object underneath here that you're actually referring to here when you declare this as a state thing and so this is wrapped in an object and that's how the state is being passed into you actually passing an object
here and it's referencing it and
so it's it's very weird when you go into the swift UI looks very clean, from the surface and as long as you follow the conventions, everything is very nice when you dig in, you realize that there's a whole lot of stuff going into like for example.
This right here is messy.
In terms of, we have this chain of things where here we get back, you know, we're actually here it's an image and here, image this and basically Scale to Fit is working on the return value of a sizable position is working the return value of Scale to
Fit scale effect is where the return. You know thing a position, you know like, there's this chain of references between this that's what we're doing when we have the start is that the return value of this is being passed on to the next function.
And really what we're doing. This is a world calling a, a method of the object that has been returned by the previous one. So we're changing method calls here.
That's what syntactically we're doing here but then you might go like, what are those objects in between.
and it's like couldn't I just call this and have an object and pass it along and represent.
You can technically, but I went in and try to figure out what those objects are and.
Oh my god.
The types of those things that are passing there are crazily complex, they're not even there.
It's not.
So I'll just tell you don't do that. It's, you won't be happy. I tried doing it for a while, cuz I thought your friends like, Oh I like got under the hood and saw what type was there because you can actually just before it was like, Oh, the type is like
20 things log on move along now.
It's because we're doing type inference, you can actually encode a lot of information in the type. So the types are much more complex than you might think.
And what you're used to.
So, Well, it's not so it's only one who understands that it's like, there is, you can look at it and see how it all works, but you don't want to do explicit typing.
So.
Oh, the only the only the people who were developed with the IRS modify the background elements, I mean,
I wouldn't. I mean, you can do. They've exposed some very nice ways to do things.
more just, there's lots of stuff going off the type system that you don't have to worry about. It's keeping track of a lot of information.
Let the implicit typing do the job for you. If you let it do it, it handles it all for you very nicely but the moment you kind of say, Oh, I'm gonna pull this out and do this it's like,
Well, it's, it's not so much West, you can be very flexible like this sort of thing here. This is very clean. But then you get these weirdness is like you try changing the order of these operations, and you'll get type errors, for something saying like,
you can't have this because it's the wrong type it's like, why, and you go in, you go like well there's a reason for it but the type systems. It's just like, Wow, so
it's not so much even be creative, but there's constraints.
And so you kind of have to do things the way they meant for you to do them. If you don't do them that if you do another way it's just like, it's not gonna work out.
So you get these things out. Okay, I have this view and I'm calling this chain of methods and you really you need to call this chain of methods. Otherwise, it's not going to work or if you're going to try doing something else use it, do it using closure
so you can do implicit typing, because notice here, we don't actually say that type of image.
You know, unlike the unlike the function here, where we pass in. And so when you.
Yeah, it's
this returns like you can say, this is why this is some gestures basically saying, This isn't a full type. This is a partial description of the type because if you tried, having the full type it would just be painful.
Yeah.
Um, I think what I was getting to, so we're calling the whole rigging I recently the chain of objects, each one, we get an object and then we call a method on it, you know, other returning object.
And these are all relatively straightforward here we sizable says that this thing is a recyclable image scale it now. Now we declared your sizable scale it to fit the view, maintaining the ratio of the you know, the aspect ratio so I won't stretch it
to fill the whole thing you can you can make skilled fit to make it stretch it.
But this, by default, does it maintains the aspect ratio, we specify the position.
The position fundamentally is the CG point, which is the middle of the in the middle of the screen so why do I have this, this thing here.
You know, remember what this this is a ternary operator.
And so what this ternary operator is has this moved Boolean what true or false. And it says, either the value of this is going to be position, or it's going to be the CG point.
What's the logic of this.
I don't know.
The logic is that when we start the program.
It starts at this point, CG point, you know, width and height.
And, but once it's moved it won't be in this position, it will be somewhere else on the screen it's wherever the user dragged it too.
So, that's the dynamic position variable here, which is right here it's a state variable.
So this, it's very important to understand what's going on with line 62 for
each program is this.
This is a picture URL.
Solutions copy that code over here.
copy that code over here.
By the way, don't cut and paste from here.
This is not what you want to do because you get the blank lines the real way to cut and paste from this is to click on this, you get this save this or cut and paste from here, because now you won't have blank lines in between.
Yeah, exactly. It's trying to condition to be met do this have to do this this fall so.
So let's see, so.
So we will move between
during the image.
So.
so if i.
So, you can't get so by the way this is there. This is a boolean variable so move can only be true or false. So the question is, why didn't I just initialize position to the correct value to this point,
because it's really weird that I have this move thing. Why did I just at the start of the application set position to.
So, this is me, why not just assign it.
And the reason is simple yet fundamental position is declared here
is G in scope.
No, it is it G is not in scope here.
G is outside of it so I can't use G to set this value here.
I have to give it some value to initialize it to something about you know valid, but
I can't.
I can't use g in this calculation, because G is only here. And so the obvious thing to do is do an assignment here in geometry reader and set it at the beginning of geometry reader.
But you can't do that.
Oh my poor fan going on here.
So if we.
So total right here. So this is, you know here. So what I want to do here is just say.
this is what I want to do.
But I can't do this.
So, to a first approximation. You can go.
Why can't you know, first of all, Jesus oh sorry I take that back. Geez not defined here so we can't we can't even think of doing it there.
But, Why am I here, G is defined here.
But
my air.
See now see build failed.
Are you
shouldn't be the air we want there and you got this error.
So let's just.
Can you add a return before the image here. No, you can't add a return here.
The problem is, remember we're inside of. So remember, inside geometry reader.
I've been returned will fix this.
Does it work.
You're saying return here,
return a sync image.
yc so you're saying.
See, so you just make this return here.
Did this using this word, where do you put the return.
So, so the reason, so what what so what specifically is the cause of that type Can I perform to view air.
Yeah, if there's if there's multiple implicit returns, if there are multiple questions inside of a function body Yes, but that's it's more than that that's going on here what's happening here is this is not a.
This is not a the.
So what it is is that inside of this, we have to do everything. This has to generate a view and the view that we're returning here. So actually, it's not even a basic images we're trying to view it's this function here.
It's returning image. And this image that's being returned, is the
or what we're guaranteeing here that return a sync image of that with a sync image will return a view one way or the other. Here, returns an image here returns a progress view.
I'm not quite sure exactly how it all works under the hood because it's doing some crazy type things, but the main thing here is we can't do stuff like this that seems perfectly innocent.
And you're like, Why can't I just assigned to a variable.
I was like, yeah, we're not going to efficiency and memory usage or something yeah now we're not going to talk about it specifically. Although I will say swift UI is very efficient.
Because it's doing all this work, static Lee.
So, it.
And in fact the entire design of swift UI is to be efficient, and it does a pretty good job of it.
So.
So, That is the real reason.
This is happening.
So the question is, how often is the body of you being evaluated.
It's.
So, potentially, the body of of you is going to be evaluated very frequently and he's like, Okay, I'm done this is going to potentially do this.
me, hundreds of times a second.
It may be a calculating the stuff at least logically, since you every time the screen refreshes
with animation, every time the screens update the body has to be changed.
This is the big thing. the state of you can't change. While it is being calculated.
This is the really the key idea to understand about with you is that you can't change state variables.
While the in the body of of you and that's really what we've done wrong here is
was the year.
So.
So what do I mean by, you have to do it in a closure function that will be evaluated later really.
that's this is the key idea you don't want to mess with the view. We're inside geometry reader.
And so if we modify position, we've modified the state variable here. And so that changes how the view is going to be rendered because that's what it means to change the state variable is the view depends upon it so now it's, you know, you're thinking
like it's going through happily okay I'm going to render the screen but Whoa, I don't know what Now what this is going to be look like, I've got a circular dependency, in effect, it goes like I can't optimize that at all so that is just not allowed.
It goes like I can't optimize that at all so that is just not allowed. So you get. So that's why you'll notice we modify that we don't modify position here, we just use it.
And the place we modify position is in these functions.
So like, Where is position so yeah position here so when they're dragging.
You know, this is well this isn't a gesture, which is, which is defined these on change things and these have.
These are functions, which will run later.
Yeah. So again, it all comes down to the return the return again there but isn't is not a syntactic issue.
So thanks for the update remark is not a syntactic issue really for a lot of this I mean it's if you just see that error means you're doing something in your view you're not supposed to like, you're kind of violating the language but most commonly is
probably because you're trying to mess with state variables.
So the state of Vermont from the state variables as part of the view update will mess this up.
So, what's really happening here with these gestures, is we're giving it a deferred execution of some kind, so here. Here I'm actually saying gesture wants and he wants a struct of type.
It wants a gesture of some kind, and gestures a type. And so here we're saying in the gesture it's going to be a drag gesture and we defined the drag gesture to be whatever it is, again, don't worry about the type so much as they get like it's some gesture
here that's what magnifying dragon is. and that's because here, that's what gesture wants.
And you can look a bit nobody can look up what's the show quick help that show anything yes so attaches a gesture to the view with the lower precedence and the just defined by the view.
So here, function gesture.
It takes a, you know, you know it takes a gesture including mass Jessica mass awesome view or Jesus.
So,
you know, you can look at that but what we're doing is we're defining this gesture and so there's a thing of like what is the gesture.
We have to use a predefined gesture.
We don't we just have to know what what are those available you can look them up. So there's a couple of ones like there's a dragging gesture, there's a magnification gesture, there's a rotation gesture.
So you use those.
You know you use these gestures to basically say, this is what you're going to do. Do we know how they work, no we've just sort of said that, but.
So we're gonna, we say some gesture, what that means is where this is going to be a struct that will follow the gesture protocol.
So, the standard gestures you want to do.
So here, we're creating a full gesture struct here and passing it in the verb drag gesture into magazines and gesture and we're saying what they are, while we have also these on long press gesture, or on top gesture, where we're just saying, okay, You
know, when this happens, do this.
I'm pretty sure I can declare on top gesture using gesture, and then say my tap gesture and create one of these things. But these are a bit more complicated.
And the main reason to use a special.
So like.
So, here on tap gesture, we ever perform it has this rotate image on long press gesture, we perform the Tap Reset function. We could have just declared the function in line here, rather than having them as separate functions, but nope these functions
are all declared as part of the struct, and they have to be declared as part of the struct, because we have to access these variables.
So, This is all.
Once you understand this idea of these met you know calling these mountains here and doing this.
That's basically the hardest with dy, you've got it then.
This is, you know, it's just elaborate elaborating this.
And no, I mean because he knows look everything follows this pattern.
And, and then you and then once you internalize that just don't update the view with dirt while it's being rendered. And so that has to always be like, I know what it is.
So, in here we can't update we can calculate a value based on G.
And that's why we have this here, but we can't change the value of position because that's changing a state variable and then it just goes. You're messing with my state variable, I would have to redraw the whole state again because you change the state
variable but we're updating the state variable so now I'm all confused and you can't do that.
That's why we do this chat here to make it so that when the view is being evaluated it's either going to be moved or it didn't. So it's either going to be this position variable which was set separately, or it's going to be this value so it's gonna be
one of those two values, they're not changing water calculating the view. So we just were good.
Does this make sense.
So, if you're feeling a little. I think this is clear once you play around with stuff and and try doing things but it's.
It took a while for me to get my head around this.
It's kind of weird.
All I will say is, this is basically all I'm going to show you of this stuff.
And after this.
We're going to switch modes, and you're going to see how to do things in the non swift UI way which is really the old school way which is how you like it does things and how standard Android apps do things, and you're going to miss this,
you're definitely gonna miss this.
Because once you see what's required to do it the other way, you'll be able to understand the code in the individual lines will be simpler, but there's going to be so many more of them.
And, yeah.
Anyway, that's unless there's any questions that's all I want to cover right now and I'm happy to stick around and do check offs.
Any questions.
Yes, go ahead.
Knowledge I just wanted to get checked out. Okay. Okay, so let me. I will stop recording and things and I will.
Okay, one question so if we add images and two assets and use image we don't need progressive you right.
Yes, exactly. You don't have, you don't use progressive you if you just have an image because there is no progress to be shown and in fact, it doesn't make much sense, because the images there.