This exercise is actually a kind of wrap up for everything we learn in this section.
It's actually a very demanding exercise on the goal of it is this you have to find a way to use a combination
of touches to do a transform on a given object.
You want to be able to a scale an object using touches as well as a rotating object using touches.
So if user puts one finger down on one top on the device and moves that that's going to essentially
rotate an object.
And if those two types sound you have to be able to scale that object.
Or let's call it a UI view.
For instance there is and I said it's a demanding exercise is simply because you have to be able to
find your way around finding how many touches are there and then finding the distance between them.
If you're going to scale something as well as finding the angle that is being used at any given time
if there's just one touch Now I know it's a difficult one perhaps and you might want to spend some time
researching it online but they still suggest that you actually give it a try on your own and try to
find some references outside before you look out.
My solution for this exercise really help you in any situation that comes to using C.G. transform.
And the combination of touches.
And of course you could do all of these simply by using gestures but they want to make sure that you
get a sense of everything that touches they do for us as well.
So I'm going to pause the video for a few seconds that you can pause it now and get it started.
And once you have done it hopefully or if you want to look at my solution you can resume the play by
OK.
This code works code and I'm going to start a new project.
Then I call it transform it.
Touch
and in my transform with Tadhg I'm actually going to do everything in the programming side so I don't
need to go back and forth between the Interface Builder and here.
So in here I'm going to go ahead and say I have a variable let's call it that red box which is of the
type you I view.
And then in my view the load I'm going to go ahead and say red box becomes a UI view of a frame that
is going to be let him auto complete those for me that say 0 0 0 200 and 200.
And the reason I stick it at 0 0 because it's a it's something I'm really used to.
Which is what I would want to do this kind of test stuff.
I just say my main object in this case red box.
It becomes at the center of the scene.
So it gets a red box that sento self that you that center.
So you put it wherever you like it.
And then we center it against against the view and then self-taught if you add the sup you read you
or a box and then the red box the background color becomes a color dot right.
I'm also going to add one more thing which really you don't have to for you I use.
Just in case some of us have forgotten and I'm going to say red box start user interaction enabled is
true.
So it makes sure that this object is user interactive and if you run the application by now we should
see a red box of the size 200 and 200 somewhere in the middle of our our simulator which is exactly
what we expect it to be.
That's that.
So now the important thing we want to do next is finding the two ways that this thing will be manipulated.
So I'm going to say such as move it because that's what I care about.
And then the touch has moved I'm going to have two distinct situations.
One is if one touches that counts was the one.
So in this situation I'm going to write it rotate and then I'm going to have another one else if touches
that the count was two and then I'm going to say the OK.
So if there's only one touchdown.
When I wrote it.
If the two touches down we want to escape now in both of these I'm going to get my touches so I'm going
to say touches one then let's say let's touch one or might touch one or touch one is better then obviously
it becomes a touch as does the first.
That's the simpler one because simply we know there's only one touch.
Now if there are more torture's because this is a set we can't just get the touches from it we have
to actually either iterate through all the touches or we have to convert all stages into an array of
touches which is what I'm gonna do.
And when I say let's touch as array for instance that becomes an array of touches.
So we get all of our touches on we place them inside an array.
And since now they are in an array we can get them by number essentially.
So I could say touch one.
I actually don't like the naming that has numeric values and it was kind of contemplating in my head
I'm going to call it touch of one so down that I have that I'm going to say here touch one becomes touches
Ray and that become the zero object of it.
And then I have touch too which becomes the first object or an object as a location one.
So Dawan that part is taken care of.
Now the important thing and the next important thing that you have to do is you have to make sure that
in most of these situations things only happen if we are touching the red box or the red the view or
the red box.
So yes I'm going to say you touch one dot view is not red box then let's do this let's return.
You don't have to continue on anymore.
So if there was only one touchdown but that one touch of wasn't on the red box don't need to do anything.
I'm actually going to do the same thing in here.
What in the in the scale.
Because the two touches I have to say touch one and touch two.
If both on not on the red box then returned.
So that really takes care of a big chunk of the problem.
It makes sure that we only do things if we are absolutely on the on the red box.
Now is also giving us an error I think is because of the optional thing.
Yes because our touch has a rate is not an option.
So we don't have to have the question mark for the touches.
The Post absolutely do exist.
So that wasn't taken care of.
Now it becomes about actually doing the rotation or a scale.
In this case during the rotation if there was only one touch and in this case doing this scale if there
was two touches essentially reformat things a little bit so I know what I'm typing because it's going
to become a longer code.
So I want to make sure that you know I have it easier for you guys to view.
So the view of the is taking care of the touches are taken just now the next thing is you have to actually
calculate the values for the rotation and for a scale.
I'm going to go ahead and deal with the rotation first and for that I'm going to write a new function
and then say function let's call it one rotate action and then rotate the action is going to do.
This is going to get two values in one of them being the touch that we landed and the other one being
the view that you want to rotate and then it's going to give us a value.
Not before I tell you what all those input arguments and what's the value you want to get back.
Let's have a quick look at how this is going to be processed.
So imagine your user taps on this location which is the last point and then pushes down the finger or
the top goes down.
And then you get to the end point.
And that team is out for that angle is the one that we want to calculate.
So the difference between the angle between the start point and the center of the main view compared
to the angle of the end and the center of the main view.
That's what you want to calculate.
Now here's the thing there's a little bit of mathematics involved and I don't expect you guys to know
it or if you are like me you would just go online and Google it and that's what I did.
I'll try to find out.
How do you calculate the angle between two points.
And it turns out the arctangent move is a very good formula for it like there was actually the first
head showed me there's an arctangent 2 and there's my discussions on a stack overflow that you can read
them again.
You're not supposed to know these things is just another off.
Once you once you reach a place that you need to find it you should be able to go online and find the
answers if you ask me to calculate the distance between these two or the rotation between them.
I would definitely want to be able to do it now with that in mind.
This goes back to school and save for a rotation.
I want to have the torch that is going to essentially give me the values of the locations.
I also want to have a view which is the UI view that is our main view or the view that we want to compare
against.
And once that is done I want to get a C.G. float.
I want to get the amount of rotation.
Now here there's going to be a little bit of a code but most of it is actually very simple on the part
that is a little bit difficult which is that mathematical side of it we just get it from some online
resource.
So the first thing I'm going to say let's kind of point wishes the current location of the top that
would be touch dot location in view and the view is this input.
So this is the current location at any point.
So I'm going to go ahead and say if that's the case thing give me the previous point that's going to
be touch dart previous location in view the same.
So essentially if you were to translate it here this would be the very first one previous location.
This is the kind location.
Of course it doesn't happen like this.
It doesn't have such a big jump.
It is being collected in every drop count.
But for now we can assume this is kind of an illustration of it.
So we get these two points was we got the two points.
I also want to get the center of the view so I'm going to say let's center to be view data center.
So I'm going to get the center of this view and the reason I gather this one is even though this is
going to be self cut view I want you to have it in case you want it to rotate against a different center
essentially.
So with that I'm going to go ahead and say let current why this is the Quine's location of X or Y doesn't
matter.
Y is going to be center dot y minus the point that y.
So that's the light.
So I'm going to copy and paste that make it current X is going to be X and X.
So what these two values show for us is essentially dislocation dislocation devoir x and y are feet
compared to the center is in my screen right now those values for instance.
So that's what these two values represent for us.
And since we have the current ones we also have to get the previous ones.
I was going to say give me previous y to B and previous Y to be.
And those are the same thing as before.
Previous point and previous ones.
So we find that wherever we used to be and whatever we are now.
So the next thing is finding the actual angle between these two at any given point.
So I'm going to say let client angle be arctangent to all the current Y and current x.
So there's a formula that essentially gets you the angle of any point against the center of the view.
And then I want to get the same thing for just a socket or B she's going to be the previous angle.
So the previous one is going to be previous Y and previous x.
Now again I'm going to have to emphasize on this that the mathematical part of this is not a is not
the goal of this lesson.
Essentially this is a formula you can simply find it anywhere online.
But for us we found the contango we found the previous Nanga.
So what we have to do is we have to say return anger minus previous Sinar.
So we have to get what has changed because the new one.
Verby before return.
The difference between these two.
And that's exactly what we needed because we needed to have a CGI float that is the rotation that we
have.
So now that you have that let's go ahead and use it in our teachers.
You know touches off if there was only one touch fish we have to rotate.
I'm going to go ahead and say let.
New rotation.
And maybe the whole thing would become rotate action for each one between self.
You remember I said that since we are using so that we could simply use it in here.
But I wanted it to be a separate value about so if we can actually make sure that you could use it for
other things as well.
And he's giving you a warning about touch one being on wrapped or not.
I mean aren't up this actually.
So this is the new rotation that gets calculated every time the touch moves.
Now we have to use it to actually rotate the red box.
So I'm going to say Redbox thought transform becomes Redbox that transform that rotated by their value
you know new rotation.
So the value of the new rotation is going to be the amount of rotation that we want to rotate the Redbox.
Ok then so a lot of call with the let's see what you have done I'm going to run the app to make sure
that we haven't done something terribly wrong.
I know something is coming up and I have to explain to you guys but let's see the rotation first and
I rotate.
It rotates perfectly.
So when I tap someone on the red one it rotates based on the movement of my mouse at the moment or a
tap on the actual device.
If I touch outside nothing happens.
Now the next thing we have that I get is the escape.
And look what happens when I try to escape now which we haven't really done a scale part than I type.
It is still rotates even though it has two taps down on the device.
It actually is still thinks there is only one rotates the object.
And the reason for that is there is something called multiple touch and the multiple touch is not enabled
yet.
So here in the view that lot I'm going to go ahead and say the red box doth multiple touch enabled.
True.
So for you my view is user interaction is by default.
True but multiple times is not for most other outlets such as you or I.
You make you view even the user interaction is not by default enabled.
So what about your neighbors.
And if you read on it now.
Now when I do two taps nothing happens.
So even I try to do with the toothaches it knows that if you are here and obviously nothing is going
to nothing is going to happen.
So that's where we have to.
What we have to do now we have to find a way to scale this object and scaling is actually going to be
a lot of code.
But the good news is is actually going to be a lot easier than the rotation.
So use that function I want to use for a scale.
This was the route that I can go ahead and say function.
And this one is going to be on a scale action and for a scale like shit I need to give parameters all
three inputs values one of them is the first touch.
So I'm going to say Tyche let's call it impotent.
One input Tajh because the other ones are called Touch one and was well.
So that's going to be a touch and that I have input touch to.
And I have a name put to view which is going to be the UI view.
And then at the end we come back with a CGI float.
The amount of a scale like that actually a stack them so it's a little bit easier to read everything.
So that's about that.
So we have to touch as I should have had that.
Here we have the two touches and we have the view that we want to calculate the scale against.
So with that this go ahead and get a few things in here.
First of all I need to find the current location of the torch one and current location of touch to and
the previous location of touch 1 and previous location of the arch.
So a lot of our stuff.
So a lot of let's call it the one that becomes input.
Touch one dot location in view and that's going to be an input value.
So let's first get the current location of touch 1 and I'm going to say Get me the second one touch
to.
And that becomes touch to perfect.
Now let's go ahead and get the previous locations and for this also I have a little and illustration
I can show you.
And the illustration is this one.
Imagine this is the starting point the top one and top two and these are the kinds of points type 1
and top two.
So the rotation is kind of irrelevant in this example.
It's just an out of the distance between the two taps at the beginning which becomes the previous locations
and the current ones I have named them be the start.
And so tap one and top two and end up one on top two.
So we have to find their complications as well as their previous locations.
I'm going to go in here and say give me these two coffee then I'm going to call them previous location
1 pre location 1 and that's going to be previous location.
Perfect.
And when I replaced that there and that becomes pretty as well.
So by now we have managed to get that complication of touch 1 and previous location of such fun as well
as the same for type 2.
The other thing we have to do is we have to now get that distance between chose 1 and 2 in the past
and the distance between the touches 1 and 2 in the current time.
So we have to kind of get that distance between them to get to the stands.
I'm actually going to write a different function.
Going write it down here so we can kind of see everything together at the same time.
So yes I'm going to go ahead and say Give me a function called this sounds action friend stance and
the distance action essentially gets two points.
So I'm going to say points 1 or input points.
One important points one that's going to be a C.G. point and input point two and that's going to be
a CGU point as well.
Either it has a CD flossed so it gets two locations and gets me the distance between those two.
So know I'm going to say rather this dance this is going to be a CGI float.
And I have to make it up on and off it then I'm going to say the calculation between the distance it
needs a firm.
This is a much simpler formula and if you remember it from any time in high school it's essentially
the square root of the square of the difference between the excess plus squared off the difference between
the winds and the very quake you know search online can get you down.
So that's essentially the point A and Point B and the distance between get access under ROIs and the
square root of that it gets you by the distance between them.
So that's what I'm going to write so I'm going to go in and say let's let's call it X def right.
That's going to be I have to get the point.
One input point one dot X minus input point to aim point who Dauth x.
That's the difference between the axis.
Let's go ahead and get Devoy difference.
So that's going to be input difference between the VI and voice.
So essentially So far we have managed to get that little part inside the Panthers and this one inside
the two parties.
So we got the differences between the x and y.
Then I'm going to say Let x square down would become P or W of X difference to the power of two.
So that's essentially powering it up.
And then I'm going to say why Esquith becomes Y difference which is this one the power of two.
And then the value that are actually interested in is adding these two together and getting a square
root of it.
So I'm going to go ahead and say Give me the distance to be this q r t of X A squirt plus y a cyclist.
So this task becomes the square root of the added value of both of these.
And then you obviously have to return the distance and the moment I do that we have to this error should
disappear essentially perfect.
And now I could go ahead into my scale action the action that's going to calculate these distances for
me and say let current stance to be dishtowels action between the current distances between the crimes
locations so collocation one Quine's location off point two.
And that's going to give me the current distance between them.
So let's go ahead and duplicate this or let me rewrite it so it's a bit more expensive.
So I'm worried I'm not going to say let previous this time is going to be this town's action between
previous location one and previous location.
And as you can imagine because we're going to get them through the power of two sometime later it doesn't
matter which is it first which means within seconds.
It's essentially a distance between them which is always an absolute value.
It sort of has a positive value.
So I'm going to go ahead and say well let's let's call this one how to put a scale or a scale ratio
which is a much better name for it.
That would essentially become current stars divided by previous distance.
So this is the value I'm interested in.
The value of how far they are against each other now compared to before.
And once we have that value was when I'm going to say a return to scale ratio.
So that's my scale action and that's perfectly taken care of now.
So the next thing you have to do is finally essentially using that value in our touch has moved so much
has moved is here the first touch we have taken off the second touch is the one that you still have
to do things about it.
So if you had that I'm going to go ahead and say let's call it let in your new race you're not just
going to become the name of my action scale auction.
So your issue is a scale auction between touch one and touch to get even with Team self to view and
then and then that's it.
And then calculate the ratio.
And once you race you I'm going to say Redbox that transformed becomes red box that transformed the
scale by giving me how much do you want to skate on X and how much on the Y.
When I say new ratio on.
So that's about that's that's running this up now.
And if all works we should have a functioning that rotates and Askins any object or essentially the
red one for an hour.
So that's the rotation and that's the scale.
Perfect.
So everything is working on that.
We have very quick clean up of the code and it's a very good exercise and something that I really recommend
that you guys do it.
So there's a lot of code in my view control and I want to put them in separate extensions so that I
say give me a new file.
This is going to be a swift file of the $0.00 Plus let's call it a scale action so you want to enter
up there I'm going to say you like shit and I'm going to say this is an extension to view controller.
And within it we have this scale action.
So I'm going to cut this fart with it there.
So the code becomes a lot easier to read because every file in here will have only a limited amount
of stuff in it.
I'm going to copy this one because I know it is going to happen again and I'm going to say command and
you've me on file and this one is going to be a view controller.
Plus this sounds action.
This is the one that calculates the distances for us.
And again it's an extension of view controller and within it we have the distance action going to cut
that.
Put it here.
So that part is taking off.
Another copy of these commands.
And swift fine.
I'm going to call the view controller plus rotate action rotate action and he has a forcefield going
to put all rotate action which is this one so perfect and if I go back to my view controller I now only
have the view that lot which are the things that are kind of neat them yeah as well as the touches are
moved if you wanted.
You could even push the touches and move somewhere else.
But I usually keep the kids Mather's VTM the main class declaration but it depends on the complexity
of what you have.
If you wanted to you could actually separate them even fair that is essentially an exercise of marginalising
or partitioning your code which surely simplifies reading the parts of the code to understand.
A They are very independent pieces which is the core understanding and the core concept of object oriented
programming and B that you can you can use them separately whenever you need them.
So that's about that.
The app is working properly or the way you expected it.
It's a kind of scale or rotating object.
A very good exercise in understanding are different things that you could do graphically and using a
combination of instructions and obviously in the next lesson.