Objective-C iPhone Programming Lesson 8 - Drag to Move
Hey guys, this is my cousin Olin with our eighth iPhone programming tutorial. In this tutorial, I'm going to be showing you how to make a UI view that you can drag around the screen. I'm going to be showing you two ways to do this; one way you'll understand is pretty simple, and the other way is a bit more complicated. It will make more sense later when you learn other stuff, but for now, you're just gonna have to go along with it.
So, I'll go ahead and create a new project. This way, I'll create a view-based application, and I'll call it Simple Drag. Alright, and what we're gonna do is have the user drag around a view and change where it is using their finger. You're going to have an IBOutlet UI view, and we'll call it liveView. I'll set this up in Interface Builder, and we will have to use Interface Builder again later when I show you the other way. But for now, I'll just set this up in Interface Builder, so I'll make the size and set the number of your 900, and I'll center this. This is the view that they're going to be able to move around; it's just a white box, pretty much.
Okay, only when I face builder are open. So, here's what we're gonna do. In the ViewController, here's the .h; we're not declaring any ID actions or anything, but in the .m, we're going to be writing code. This is kind of like viewDidLoad, how we don't declare the method; it just gets called magically. There's a method called touchesMoved which has these arguments, which gets called whenever the user moves their finger.
So let's put an NSLog in here; put this up, and every time I move my finger around the screen, you can see it says no matter where I touch, as you can see right there. So, I'm dragging my finger; we're going to move my mouse without dragging it. It doesn't see me, alright?
So now that we know that this gets called every time they drag their finger along like it should, you can get the point that they touched in. To do this, we say CGPoint touch = ((UITouch *)[touches anyObject]).locationInView(self.view). The touches is an NSSet that is like an array; it's a list, it's an unordered list, and anyObject just gets the first object that it can find in the list. So basically, how "anyObject" will give us the touch, the UITouch of their finger. If there are multiple fingers, then we shouldn't call "anyObject."
What this does then is we get the location of the view, we're asking for, alright? I want to know the point where their finger is in this view. For the view, we're passing self.view because this is a UIViewController and it has a .view property. So now we're going to say myView.center = touchPoint. Just like we can move it to any point, we're doing that here.
And now, if we run this, I can drag my finger, and what we do it follows it, but there are a couple of problems. First of all, if I start dragging from the corner, all of a sudden, it moves to the center. If I start dragging here, all of a sudden it moves here, so it doesn't—you're not pulling it; it's jumping to where we're touching. That could seem good to an iPhone user who has a big finger and can't really tell what's going on, but for us on this computer, it doesn't look the best, and to be honest, I don't like it this way very much.
So there's a more complicated way that involves objects where you can create an object that allows you to move this around, and I'm gonna be showing you that. I can't really explain it to you guys yet, but you'll understand it later. So, we're gonna go to New File, just like we're creating a new view controller, but instead, we're going to create a new Objective-C class and make it a subclass of UIView.
And so here, we're creating a custom view, and I'll call it DragBox. Okay, and in the global variables of this, as you can see, zu argue now the UIViewController. Anyway, in the global variable, we're gonna write a CGPoint which is our start point, and this is going to be the place in the square where they touch something. Touch the top left corner will be (0,0), (100,100), yeah, so that's what this is going to be.
So the way we set this in here when you start moving in our UIView, we can also, in the UIView, implement touchesMoved. If you'll notice I'm editing DragBox that I'm not—then you can fill about it in there. I'll make a CGPoint center = ((UITouch *)[touches anyObject]).locationInView(self), and I'll just say startPoint = that, and there we go.
Now here's the thing. When they move their finger on our custom view, it's going to set the start point to where they are. We want to set the start point when they start—when they touch in the view, and then when they move it, we will use that. So in touchesBegan, then we're going to put our magic. So this is touchesBegan; we're setting this now. In touchesMoved, we're going to use that so you know where their fingers started. We're now going to get a CGPoint newPoint = ((UITouch *)[touches anyObject]).locationInView(self).
So it’s not super me. Now, if we move this, let’s say we started dragging from the top left corner. If we moved it so the top left-hand corner, which is the X and the Y, was this, then it would look fine. But if we start dragging from here, then we would be dragging it, and all of a sudden, its top left corner would be here.
So what we're going to do is offset it by our start point. You're going to say newPoint.x -= startPoint.x, and newPoint.y -= startPoint.y. Now we're going to say CGRect frame = self.frame; frame.origin = newPoint, and we're going to say self.frame = frame.
Now, if we do this, we just go ahead and run this—ah, nothing will change. And you might be thinking, "Well, lad, I wrote all this code in here; if I don't mean not to use it, because you just wrote this code in UIView, but you didn't write in your view controller, so what's going to change?"
And the answer is that you have to use this. In order to do that, first, you have to import DragBox.h, which is your custom view, and then you're going to make a new IBOutlet and we just create our own data type called DragBox. We will call it myDrag. Okay? We're not going to do anything with it because the code is already written in there.
Back into the Interface Builder file, but I left it open, so this is going to be a DragBox, so this is an IBOutlet, yeah? This is a DragBox, that's an IBOutlet. I don't—we don't really need to Allen that; I'm elevating. Thank you.
So now, if we run it, those treatments—and the difference is that if we go ahead and run this, then when we click and drag anywhere, this one will move with us. And if we click this one and move it, it'll move by wherever we drag it. So if you click it in the bottom right and we're dragging it by there, it doesn't jump to the center. You can drag it from the center, but we can also drag it anywhere else, and it'll work fine.
So it's slightly smoother UI. If you get rid of this, then this will be standalone. Hell, I mean obviously if you put these over each other, this one's on top. It's hard to tell because they're both white, but yeah.
So that is how to make views movable. In the next tutorial, I'm going to be showing you how to save the location of views using UserDefaults. It's pretty straightforward; I'm ready giving you a clue in the last video. But anyway, that's how to make things move and draggable for the iPhone.
So thanks for watching. Make sure to subscribe, and goodbye!