I am implementing a draggable UIView in my application. The codes I have worked fine but I would like to set a restricted area the UIView can be moved.
My codes:
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == camview)
{
CGPoint location = [touch locationInView:self.view;
startX = camview.center.x;
startY= location.y - camview.center.y;
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == camview)
{
CGPoint location = [touch locationInView:self.view];
location.y =location.y - startY;
location.x = startX;
camview.center = location;
}
}
So how can I set the minimum and maximum y value that the UIView can be dragged?
Thanks!
If you are interested in making sure the view frame doesn't go over or under a certain y value you could do the following,
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
CGFloat minY, maxY; //The position in your self.view you are interested in
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == camview)
{
CGPoint location = [touch locationInView:self.view];
location.y = location.y - startY;
location.y = MIN(location.y,maxY); //Always <= maxY
location.y = MAX(location.y,minY); //Always >= minY
location.x = startX;
camview.center = location;
}
}
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;
}
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;
}
}
i like to drag this object vertically instead of horizontally, which is doin it now:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
if (CGRectContainsPoint(myObject.frame, location)){
CGPoint xLocation = CGPointMake(location.x, myObject.center.y);
myObject.center = xLocation;
}
}
CGPoint yLocation = CGPointMake(myObject.center.x, location.y);
myObject.center = yLocation;