Use custom gestures to determine custom behavior by our users on the device.
Imagine if you want to find out if your user is drawing something similar to a circle or if you want
to find out if they are pointing in a certain direction.
All of those we can actually achieve them by custom gestures.
And in this list then I'm going to actually show you how to find the way that you use it has to draw
a certain direction on the device.
And if that direction is correct they get a they get a notification saying that they have drawn in the
right direction and if it is not they get a chance to redraw it.
This could be useful for any situation like when you want your user to draw projects or in a video game
for instance or anything that you might come up with.
Now in this lesson particularly because it became a slightly longer code I decided to actually develop
the app for you in advance so I can actually show it to you.
So if you go to school and into a simulator this is the end result that if you're going to see the app
has a very simple interface.
Every time you read the roll you get two different points start and start and and your user can drop
in here or move their top.
And as they move their top they get some sort of an indication of which direction they're moving.
And if they do draw in the same direction from the start two ends of this one they will get a notification
saying that you found the direction.
Any other thing it tells them that they have to try again.
Now in my example only thing that really matters is that the direction you could actually expand on
this and make it in a way that it has to start from this point or somewhere near this point and be on
the right direction.
So that's what you're going to do is going to be a slightly longer piece of code but I think it really
helps you understand and master everything that is out there about your gestures.
With that let's go ahead and get this thought that I'm going to go to explore to start a new project
called it costs just shows and the first thing I'm going to do is I'm going to add my interface items
so I have a label up there that's going to be my result.
But it shows us how well or use or how I was done.
So that's my result to label make the link.
Now it's really quickly that is the result.
I have a you I view which my YOU view is essentially where your user can play the game.
So that's the playable area essentially.
And we have a button this then redraws different items to start and end.
So now I'm going to say read the roll and read the are always going to be maybe like that.
I'm going to make the bag you're on to have a slightly different color.
So you can see everybody else.
I have another label.
This is going to have a different color such as this.
I just call this thought and I have another label and this one actually says and
let's go ahead and are these outlets
so this is going to be resolved later.
This is going to be a view.
This is going to be a start labeling.
This is going to be an down this one is going to be a read the role action that's about that.
That's all we need to have in our storyboard.
So the school had to view controller when a format is a little bit better because I know that you know
we're going to have a lot of code to write action.
And this is our view that a lot.
Maybe I'll clean that up as well.
And I need to have a few other things as well.
One of them is that I need to add a new class that is going to be my actually my gesture recognizes
something to say class.
So I'm going to call it my my classroom gestures my costume gestures.
And it's a subclass of your gesture recognize.
So that's one.
And then in my view controller I'm going to have to get one of those and use some of those.
So I'm going to say wow my simple gesture that's going to be just sure that's going to be of the type.
My costume just show i hate myself.
I need to have two locations because we need to be able to randomly place these two.
So I'm going to get to C.G. point for those that say route points one that's going to be a CGU point
and I'm going to have a point too.
And that's going to be a CGU point as well.
And the next thing I want to do is I want to be able to redraw these two labels every given time that
they needed.
So I'm going to go to read the wrong action and you might read the raw.
Essentially you have to do this.
I have to say it starts labor data center to become something new value.
And I have to say and the label DOD Center to become some of you value you and those new values you
have to essentially produce them randomly.
So I'm in here and say Let's first make a random location for each of these two numbers.
So let's first produce a Rand on location for point 1 and point 2 simply because these two points are
the direction we have to go through and also are there these two should be placed that's and that's
going to be a little bit of a long record.
But bear with me.
So I say let around X let's make that become an arc for random uniform with an upper bound of the roll
view dot frame that size that at the moment you do that you will end up getting an arrow and that arrow
is it's essentially because the type of the variable here is not the same as what the function is expecting.
This happens a lot on an escort and you get a different kind of Arrow.
The arrow says the type of file is ambiguous without more context simply because it can not translate
it to the type of function.
Most often when you when you have this kind of error it's the type of Marybel is not the same as the
function is asking.
So don't fix that at least in this very instance.
I'm going to say well let's do a you end tested two which is what you expect of this right.
You don't get myself a little bit more space because I still need to write quite a bit of code.
So now we got a Orrick for random but that's a random value is a you incertitude itself.
So if I wanted my random x to be essentially a CEG float which is what I want it to be.
This is not going to give us an error because it's going to say one side of this equation is a you inserted
to the other side is a C.G. float on the suggestion that the House is to essentially cast this value
into a C.G. flawed.
But just let me get myself a little bit more spaces then.
And now what we have is we have a CGI float value all of this random location which is based on the
vet of the droll view.
So we got the X taken care of and I don't need to have this explicit notation.
And in the interest of saving a space I'm actually going to remove it because we know it is a C.G. float.
So now I'm going to get the same thing.
It say this is why.
And this is height and obviously then when I play both of these to make my point one so point one becomes
a point of these two value random x and random Y and my start label can essentially be at point 1.
So I start laborer's center goes and point 1.
Now we have to read this process once again.
Four point two and that's going to help us with the Enderley but.
So I'm going to go ahead and say let's copy most of these.
One more time again.
This time we don't need to do the left part.
And we actually have to convert these two into variables because you're trying to change them and we
are redoing the random generation again.
Remember if we did it once the boss of these will be at the same point.
But since we do it once and replace the first label then we do either.
And if it breaks the next label they end up being at the right spot.
So next one is going to be point two which is going to be a CGU point of these two locations run X and
run.
And of course the center of the end the table becomes point to so if it all works well by now we should
have an app that when we run it every time we press the reader or button it redraws to new locations
for our labels for the locations of the labels.
I should mention that I didn't really icons for the borders.
If you want to be super careful about it you can make sure that they never go in and out of the view.
But for now I think they can just live with this.
So now every time I first read all but then I get to new locations for a start.
And so now we have these two taken care of and I'm going to have to move on with my actual gesture.
So retro action is taken care of.
Let me fall that forward and now I'm going to go to my view that lot to add gesture to let's say my
simple gesture is my custom gesture.
And that's going to have a target that's the default superclass in it from you or just your recognizer.
I'm going to say target itself and the action is let's say a select four for something called just sheer
action which you don't have yet.
So I'm going to say let's add that function gesture action and that's that.
And it has to be exposed through Objective-C.
And once I have that I'm going to go ahead and say well draw a view does I just show recognizers and
then just say I want to add is my simple gesture.
Now let's see what we need for or just to actually do for us what we need to do is this.
I'm going to write them as comments find the angle between points 1 and to find the angle between starting
and ending points.
All that just share and compare them against each other.
So we have to find the angle between the two points which are essentially these two guys.
If you have to find the angle between where the mouse is moving then we have to compare them.
If it was within a certain tolerance acceptable value it means our user has done well.
If not it means our user has essentially messed it up.
So to do that I'm going to first go through my gesture because we're just sure we need to have this
thing.
The angle between a starting and ending point which is not a difficult thing from any gesture.
So we have to you have to build that ourselves.
So I'm going to go ahead to my gesture in here my gesture class and what I say I need some valuables.
First of all I need an anger and I'm going to say that is a C.G. float is the default value of zero.
The next thing is I need to find the starting and the ending point.
So I'm going to say that the starting point that's going to be a CGU point and ending point that's going
to be a C.G. point as well.
Now every should recognize that can override that to the main touch functions.
So I'm going to say touches began.
That's one of the functions we're going to use.
And let me reformat it properly.
I need touches.
Move that's another one you're going to use the imagery for my dad when I was a mess myself.
Get myself a little better space and touches and and soon you will see that most of the code that you
have to write it is actually very simple.
So the simple parts are these.
The starting point becomes touches on that first that location in view.
So now we got the very first point based on where the touch began.
Then you get the ending point in touches and that touches on that.
I'm going to say that is exactly the same thing as before.
First location in view view and the view refers to the default view of the gesture.
And since we are only applying it to one of you it doesn't matter for us.
Otherwise you could actually have a custom in it to take care of this part for yourself.
So that's taken care of.
Then the next thing is this you have to find this angle between these two different locations for a
starting point and the ending point.
And more importantly we have to set the estate of the gesture.
So I'm going to say that touches begin.
We're going to say a state is going to be you I gesture recognize that the state DOT began.
So our gesture is now active.
They didn't yet didn't.
And then in the touchiest and that I'm going to say well a state is going to be you I just should recognize
the state DOT.
And so now we know where it begins and where it ends and everything in between is the move part which
we really haven't done anything about it just yet.
Now let's go ahead and count the actual angles between various thought that and where we ended the first
thing I'm going to do is I'm gonna assume my Usenet is going to run this several times.
So every time that they begin I'm going to set the angle to zero.
When I say angle is zero.
Every time the touch begins.
So over time at the very beginning we don't have any anger.
Every time the touch ends and the estate ends squarehead and say anger and just a bit of a mathematical
formula I think I've mentioned it somewhere else as well.
If you don't know it it doesn't really matter at all.
I don't know it either.
I went online and I Googled it.
So it becomes an arctangent.
Two of the defense of the voices on the defense of the excess.
So essentially ending point dot y minus the starting point.
That's why the next argument of it is going to be ending point dot X minus a starting point DOT takes
and that's all there is to it.
So this formula is going to calculate the angle for us and it has an error for me for some reason.
MC What does it say ending point value of as you point has no number.
Varies.
Oh OK.
So why not to say that that was my dad.
And yeah that's about it.
So we now can calculate Yangon before I move one to actually test this out.
I want to show you a very very simple way.
Another very very bright way to be honest for showing the direction where your user is actually drawing.
Here is my strategy.
Hear me out when I begin moving for every word I move I draw a little you I view with the color red.
So every time I start moving for every where my mouse goes or my top goes I draw a little box and that
box is going to be added to this view and at the end I'm going to remove them.
So when the touch ends I'm going to get rid of them.
So let's see how we'll do that.
And yet in my gesture save valuable temp boxes it's going to be an array of views and it is going to
be empty by default.
So these are the temp boxes or templates call them temp guides better name.
So every time we go toothaches moved and that has nothing to do with the touches began or that just
ended on the touch has moved.
I'm going to say Let let's call it this guy.
I'm going to make it a new high view of you I view with that frame and that frame is going to be 0 0
and of itself may be five on five not this number that don't really matter.
I'm going to say this guy will have a background color of white color red.
So it is quite distinctive and this the most important part of it.
That sensor is and touches that first dot location in view.
So we place them exactly where our touch is currently on this location is obviously optional so we have
to force on it to make sure that it actually exists.
And then I'm going to say view that our sub view Guide to it.
So now we end up adding so many guides to our view.
But we should also have a way of removing them.
And that's why I have that array.
So I'm going to say temp guides that append guide.
So this way we end up making sure that we have a store them somewhere and we can get rid of them.
So when do we want to get rid of them.
Obviously when the touches and so vendor touches and I'm going to say well for any in temp guides do
this any DOT to remove it from Super of you.
So anyone in the temp guide which is it all the guys that are currently stuck to the view they removed
them from SuperValu.
Once you did that say temp Kite's is empty again.
OK.
A lot of code.
So by now we should be able to see at least these guys.
So that's a good thing because it kind of gives me a little bit of confidence that I'm doing the right
thing.
Having the visual feedback usually.
So now if I do that's perfect he's actually showing me that I'm actually drawing something at least
whether it is in the right direction or the wrong direction.
I don't know that much just yet but that will figure it out real soon as well.
So to get us started with that let's go ahead to or just share function which is here.
And I'm going to say that's print's two values one value is the direction between the two points which
we have to calculate and the other one is the one that our gesture has produced.
So I'm going to say let's just call this one current angle and that's going to be arctangent to very
similar to the one we had before.
Of point to remember this one ending point point two to y minus point 1 that Y and the other side effect
is going to be pointed to that X minus point 1 that x.
So that is going to be the angle currently presented between these two points.
And then we also have a point 1.
I don't know why I constantly make this mistake.
And then we have the angle that we received from our gesture being recalled called my simple gesture.
So I'm going to print some values.
I'm going to save prints and in the print I'm going to say a triple quotation marks for largest string
essentially.
And in a year I'm going to say I have these one of them is going to be current.
I'm going to ease up on the value for it is Koren's anger and then I'm going to say gesture anger is
my simple gesture don't anger.
So we end up seeing both of these values and then we can find a way for essentially comparing them.
If we had to find the angle between these two we found that we had to find the angle between the starting
and the ending of the gesture.
We found them the last part is comparing them.
That's right again and once it comes up we should be able to draw on the screen and see the values of
both of them.
If that works it means doing a very good shape.
So now everything crashed why do you think that happens now.
This is something that began to study in Inform in advance like you know 15 sections from now.
But for now if you go to your little debugger window it will tell you that Tuvalu is on point 1 and
point two.
No one has decided about them and that's simply because these tools are the default values and the default
values are actually are nil.
Nobody has actually defined them.
They only get defined the very first time the redraw action is being pressed.
So one of the solutions is we actually called the reader or once we go to view it lot.
So in the view of the law I'm going to say you read the wrong search.
And if we run the application now we should be able to see the values of most of these but I want to
remind you that it's still something is not going to work the way we expected it.
So as we run this we get so many just showing goals that are zero just showing below zero just trying
to zero.
And then sometime at the end we get an actual just showing.
And the reason for that is this our actual angle gets calculated here.
Venda touches and which is when the state of the gesture is and so in all just your function here you
have to only do this when the gesture has ended.
So I'm going to say if my simple just show this state is your ears you just should recognize the state
state DOT in bed.
This is the only time that we actually have to do this comparison.
So let's try again and this time it will only happen when our touch ends which is essentially even the
gesture ends.
So now I let go.
We see that and of course the two numbers are widely different than each other because one of them is
going a hundred eighty degrees or three point one for something around the point number and the other
direction I draw was on the top to bottom.
But if I was something like that the numbers are kind of very very similar.
And let's deal with that part.
Now the opposite is going to be the easiest one in here in my gesture function.
Let me get myself a little bit in space so I can only show you this one.
So obviously you don't need any of the print values.
What they need is some sort of a boundary or tolerance.
I'm going to say let tolerance to be let's say point two and then in the end that state of all gesture
recognizer I'm going to say let's find the difference between these two.
The angle from the current one and the angle from the simple gesture.
So I'm going to say let angular difference for instance that's going to become my simple gesture.
Does anger minus current anger.
So we're going to subtract these two from each other.
Now here's something that you have to keep in mind that these two values could be could have a different
signature.
One of them could be positive.
One of them would be negative.
And because of that you have to get the absolute value of it.
You have to get the difference between them.
Irrelevant of the signature.
And if that was the case only if he got there you know signature free value.
I'm going to say if the angle difference was smaller than tolerance.
So if the difference between these two Tango's was smaller than point two then that's what we want to
do.
So here I'm going to say if that was the case then we call this one resort label if I'm not wrong.
Yes.
So we're going to say result labeled that text is going to say you found that direction and resolve
to label that bygones.
Color becomes you.
I mean anybody else.
All the opposites happen.
So in the else it says try again.
And the gun becomes red house.
Now there is a little error in here saying you're comparing a CGI float with a double.
So the very simple solution is we make the tolerance to become a C.G. floaters.
So everyone is now C.G. flawed and that should be perfect.
Let's read on this application.
Now we don't need to print anyone anymore.
You only have to be able to see the direction and now it's the moment of the truth somewhere.
All I want to get a better space perfect if I go from a start down there because God help me try again.
If I go other way is going to say try again if I go from and to twist that says try again.
If I go from a stock to and it says you found the direction if I to start from somewhere similar to
and it's still good if I go further.
It's bad.
So you guys should decide about this tolerance on your own.
How much is pointing to for you are worth it.
And you can actually calculate the points to be point two multiplied by one hundred and eight divided
by 2.1 four.
So it's about 11 degrees.
So it is a very narrow margin.
I'd say point two is actually a good number.
I came up with it randomly what I think is a good number that we found.
So that's a lot that a complete custom gesture recognizer are benefiting from touches begin to move
then in their methods and applying it on top of a draw you to find a specific direction.
A lot of the things that you end up doing with custom gestures they end up being more about mathematics
than programming.
For instance if you want to find out if you use it is drawing something similar to a circle and then
that essentially becomes a lot of mathematics finding sample points of where your user has clicked on
trying to find the center.
Establishing a center based on that and then based on that finding out if most of them are within the
same vicinity.
For instance a drawing like this would kind of be a circle but the drawing like this would not be characterized
as a circle.
And yeah that's about it.
I hope you can manage this on your own and see you in the next lesson.