I have a UIView and on the top of him I've got UIButton, UITableView and UINavigationBar. what I want to do is, when you click on the UIButton and drag it, all the view will move to the left side only, until the screen ends. I mean that you can drag the view to the left and when you stop touching, the view will stop where your finger stopped touching the screen.
I can't do it, he shows me only the "Touches Began 1" and thats it. what seems to be my problem here?
Thanks alot everyone!
float oldX, oldY;
BOOL dragging;
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
NSLog("Touches Began 1");
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(btnOpen.frame, touchLocation))
{
NSLog("Touches Began 2");
dragging = YES;
oldX = touchLocation.x;
oldY = touchLocation.y;
}
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (dragging)
{
NSLog("Dragging!");
CGRect frame = mainView.frame;
frame.origin.x = mainView.frame.origin.x + touchLocation.x - oldX;
frame.origin.y = mainView.frame.origin.y + touchLocation.y - oldY;
mainView.frame = frame;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog("Touches Ended!");
dragging = NO;
}
- (void)viewDidLoad
{
[btnOpen addTarget:self action:#selector(touchesBegan:withEvent:) forControlEvents: UIControlEventTouchDown];
[btnOpen addTarget:self action:#selector(touchesMoved:withEvent:) forControlEvents: UIControlEventTouchDragInside];
[btnOpen addTarget:self action:#selector(touchesEnded:withEvent:) forControlEvents: UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
}
You are asking for the coordinates of the touch in relation to the frame of main view
CGPoint touchLocation = [touch locationInView:self.view];
And then you ask if the location of the touchLocation is within the frame of the buttons frame
if (CGRectContainsPoint(btnOpen.frame, touchLocation))
In another words. You are checking if the touch was within the bounds of the button but you check by the coordinates of the touch made on the main view instead of the button.
So this is what you should do:
CGPoint touchLocation = [touch locationInView:btnOpen];
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
NSLog("Touches Began 1");
for (UITouch *touch in touches) {
//UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(btnOpen.frame, touchLocation))
{
NSLog("Touches Began 2");
//dragging = YES;
oldX = touchLocation.x;
oldY = touchLocation.y;
}
}
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
// UITouch *touch = [[event allTouches] anyObject];
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(btnOpen.frame, touchLocation))
{
NSLog("Dragging!");
CGRect frame = mainView.frame;
frame.origin.x = mainView.frame.origin.x + touchLocation.x - oldX;
frame.origin.y = mainView.frame.origin.y + touchLocation.y - oldY;
mainView.frame = frame;
}
}
}
Try like this i think it will be helpful to you.
Related
I am developing one application. In that I am using one UIImageView and I am changing the position of the UIImageView every 0.5 seconds using below code.
[NSTimer scheduledTimerWithTimeInterval:0.5
target: self
selector:#selector(moveImage)
userInfo: nil repeats:YES];
-(void) moveImage
{
//[image1 setCenter: CGPointMake(634, 126)];
CGFloat x = (CGFloat) (arc4random() % (int) self.view.bounds.size.width);
CGFloat y = (CGFloat) (arc4random() % (int) self.view.bounds.size.height);
CGPoint squarePostion = CGPointMake(x, y);
img.center=squarePostion;
}
Now i can touch the screen. What i need to find out is my touch location and that imageview location both are correct or not.
use this
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if ([touch view] == photo1) {
//photo1 is image view give tag to it
if( photo1.tag==3)
{
NSLog(#"You have been touched image view");
}
photo1.center = touchLocation;
}
}
//it used to find the point in view
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = [touches anyObject];
CGPoint pos = [touch locationInView: [UIApplication sharedApplication].keyWindow];
NSLog(#"%f,%f",pos.x, pos.y);
}
I have 2 image views namely mainImageView & smallImageView. My smallImageView is added as subview to mainImageView. My smallImageView is draggable (i.e moving around the view). I want to restrict the movement of smallImageView within mainImageView (my smallImageView should not go outside of mainImageView).My smallImageView contains circle as image. Here is my code
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
smallImageView.center = location;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
if (location.x < mainImageView.frame.origin.x || location.y < mainImageView.frame.origin.y) {
[self touchesBegan:touches withEvent:event];
}
}
How can I fixed this problem. Thanks.
In both touch methods,
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
if(CGRectContainsPoint(mainImageView.frame, location)) {
smallImageView.center = location;
}
The disadvantage to this approach is that the small view moves to wherever you touch even if your touch doesn't start on the small view.
If you want to avoid this, set a 'dragging' boolean state only if your touchesBegan starts in the small view, and only respond to the touchesMoved if the dragging boolean is YES. Set dragging to NO on touchesEnded.
EDIT: Main view is a circle.
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
CGFloat xdifference = mainImageView.center.x - location.x;
CGFloat ydifference = mainImageView.center.y - location.y;
CGFloat distance = sqrt(xdifference * xdifference + ydifference * ydifference);
CGFloat radius = mainImageView.frame.size.width / 2;
if(distance < radius) {
smallImageView.center = location;
}
I am working on trying to get multiple UIImageViews to move when they are dragged. I was originally putting all the movement under TouchesBegan. However, when I drag a single object, they all disappear and only the one I am dragging moves.
How can I have each image dragged own its own terms(I drag the first image, only the first image moves etc.)?
I'm not sure if this is what you're looking for but I worked on this a while ago, so hopefully it's useful.
Just make sure you set up 7 UIImageViews in the XIB File, link them and you'll be good to go.
#synthesize img1, img2, img3, img4, img5, img6, magnet;
-(void) checkInsertion {
if (CGRectContainsRect(img2.frame, img1.frame)) {img1.center = img2.center;}
if (CGRectContainsRect(img4.frame, img3.frame)) {img3.center = img4.center;}
if (CGRectContainsRect(img6.frame, img5.frame)) {img5.center = img6.center;}
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
if (CGRectIntersectsRect(magnet.frame, img1.frame)) {img1.center = magnet.center;}
if (CGRectIntersectsRect(magnet.frame, img2.frame)) {img2.center = magnet.center;}
if (CGRectIntersectsRect(magnet.frame, img3.frame)) {img3.center = magnet.center;}
if (CGRectIntersectsRect(magnet.frame, img4.frame)) {img4.center = magnet.center;}
if (CGRectIntersectsRect(magnet.frame, img5.frame)) {img5.center = magnet.center;}
if (CGRectIntersectsRect(magnet.frame, img6.frame)) {img6.center = magnet.center;}
[UIView commitAnimations];
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [[event allTouches] anyObject];
CGPoint touchLoc = [touch locationInView:touch.view];
if (CGRectContainsPoint(img1.frame, touchLoc)) {img1.center = touchLoc;}
if (CGRectContainsPoint(img3.frame, touchLoc)) {img3.center = touchLoc;}
if (CGRectContainsPoint(img5.frame, touchLoc)) {img5.center = touchLoc;}
if (CGRectContainsPoint(magnet.frame, touchLoc)) {magnet.center = touchLoc;}
[self checkInsertion];
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
}
You should look at UIPanGestureRecognizer. In the view controller that's responsible for these multiple image views, add a pan gesture recognizer to each of the image views. The view controller should be responsible for responding to the pan gesture callbacks and move the frame of the image view accordingly.
Of note, you should also grab the offset of the touch within the image view from the center and store this. Then, when the view is panned, you need to factor in the offset into your calculations. This is so the view doesn't just jump to the user's finger if they start dragging somewhere distant from the center point.
See the WWDC session videos from 2010 and 2011 about UIScrollView. Especially from 2011. They go into examples of how to do some of this.
I have gotten it to work!
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event touchesForView:self.view] anyObject];
CGPoint location = [touch locationInView:touch.view];
if(CGRectContainsPoint(plusone.frame, location))
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
plusone.center = location;
}
if(CGRectContainsPoint(plustwo.frame, location))
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
plustwo.center = location;
}
if(CGRectContainsPoint(plusthree.frame, location))
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
plusthree.center = location;
}
if(CGRectContainsPoint(minusone.frame, location))
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
minusone.center = location;
}
if(CGRectContainsPoint(minustwo.frame, location))
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
minustwo.center = location;
}
if(CGRectContainsPoint(minusthree.frame, location))
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
minusthree.center = location;
}
But, When An Image Collides With Another, It Disappears!
Does anyone have a fix to this problem?
For various reasons, I've moved these methods from a UIView subclass to my viewcontroller. And I finally got it working, except for one thing. Not only am I able to drag the UIImageviews I've programmatically created, but the actual view controllers view is draggable too. Creating this much undesired effect. I guess it's the fact that it's touches anyobject, and the background itself is an object. I'm just not sure how exclude the background. I would think that it would need the "UserInteraction enabled", but I guess not? I only want it to make UIImageViews draggable. Please forgive my noobness. I'm still learning.
I have all the imageviews i'd want "touchable" in an NSMutableDictionary called "letterDictionary". Would it be possible to only have touch apply to what's in the dictionary?
http://imgur.com/W08dI
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
UITouch *touch = [touches anyObject];
touchPoint = [touch locationInView:self.view];
movingLetter = [touch view];
CGPoint pointInside = [touch locationInView:[touch view]];
if ([movingLetter pointInside:pointInside withEvent:event]) touchedInside = YES;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (touchedInside) {
UITouch *touch = [touches anyObject];
CGPoint newPoint = [touch locationInView:self.view]; // get the new touch location
movingLetter.center = CGPointMake(movingLetter.center.x + newPoint.x - touchPoint.x, movingLetter.center.y + newPoint.y - touchPoint.y);
touchPoint = newPoint;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (touchedInside) {
UITouch *touch = [touches anyObject];
CGPoint newPoint = [touch locationInView:self.view];
movingLetter.center = CGPointMake(movingLetter.center.x + newPoint.x - touchPoint.x, movingLetter.center.y + newPoint.y - touchPoint.y);
if (CGRectIntersectsRect([movingLetter frame], [placeHolder frame]))
{
movingLetter.center = placeHolder.center;
}
}
touchedInside = NO;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
touchedInside = NO;
}
You have the view that was touched,
UITouch *touch = [touches anyObject];
touchPoint = [touch locationInView:self.view];
movingLetter = [touch view];
just test to see if it is the class you are looking for (e.g. a UIImageView) then return
UITouch *touch = [touches anyObject];
if (![[touch view] isKindOfClass:[UIImageView class]])
{
return;
}
In this touchesBegen Method :
-(void)touchesBegan:(NSSet* )touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
UITouch *touch = [touches anyObject];
_previousPoint1 = [touch previousLocationInView:self.main_uiview];
_previousPoint2 = [touch previousLocationInView:self.main_uiview];
_currentPoint = [touch locationInView:self.main_uiview];
[self touchesMoved:touches withEvent:event];
self.bezierPath = [UIBezierPath bezierPath];
[self.bezierPath moveToPoint:_currentPoint];
}
TouchesMove Method
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent* )event
{
UITouch *touch = [touches anyObject];
_previousPoint2 = _previousPoint1;
_previousPoint1 = [touch previousLocationInView:self.main_uiview];
_currentPoint = [touch locationInView:self.main_uiview];
lastPoint = _currentPoint;
[_bezierPath addLineToPoint:lastPoint];
// calculate mid point
CGPoint mid1 = midPoint4(_previousPoint1, _previousPoint2);
CGPoint mid2 = midPoint4(_currentPoint, _previousPoint1);
UIGraphicsBeginImageContextWithOptions(self.bg_imageview.frame.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context,brush);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineJoin(context,kCGLineJoinRound);
[self.bg_imageview.image drawInRect:CGRectMake(0, 0, self.bg_imageview.frame.size.width, self.bg_imageview.frame.size.height)];
CGContextMoveToPoint(context, mid1.x, mid1.y);
// Use QuadCurve is the key
CGContextAddQuadCurveToPoint(context, _previousPoint1.x, _previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetStrokeColorWithColor(context,[UIColor blackColor].CGColor);
CGContextSetLineWidth(context, 3.0);
CGContextStrokePath(context);
self.bg_imageview.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();}
I know how to drag a view or object:
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == ViewMain)
{
CGPoint location = [touch locationInView:self.view];
ViewMain.center = location;
}
}
but I would like to start dragging that view or image from the point where I touched it. for example if I drag (I highlighted the view and placed blue on the cursor):
the moment I start dragging if I drag the mouse 20 px to the right for example then I would like the view to also drag 20 px instead of:
maybe I have to change the center of the view to the point where I fist touch it. How could I do that?
In other words I would like to do something like when you drag the apps on the iPad:
float startX = 0;
float startY = 0;
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == ViewMain)
{
CGPoint location = [touch locationInView:self.view];
startX = location.x - ViewMain.center.x;
startY = ViewMain.center.y;
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == ViewMain)
{
CGPoint location = [touch locationInView:self.view];
location.x =location.x - startX;
location.y = startY;
ViewMain.center = location;
}
}