I have an UIView inside main view controller which contain 1 imageview.i moved imageview with this method.
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
if (aTouch.view == self.sub_View) {
CGPoint location = [aTouch locationInView:self.sub_View];
CGPoint previousLocation = [aTouch previousLocationInView:self.sub_View];
self.imageView.frame = CGRectOffset(self.imageView.frame, (location.x - previousLocation.x), (location.y - previousLocation.y));
}
}
Imageview move perfect. But i have to keep imageview inside UIView when i moved. Problem with this code is when i move imageview it is also moved outside UIView. I have to keep imageview inside UIView and movable only inside UIView.
Please help me to solve this. How to set boundary for imageview so it is movable only inside UIView.
Try below code.
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
if (aTouch.view == self.sub_View) {
CGPoint location = [aTouch locationInView:self.sub_View];
CGPoint previousLocation = [aTouch previousLocationInView:self.sub_View];
CGRect newFrame = CGRectOffset(self.imageView.frame, (location.x - previousLocation.x), (location.y - previousLocation.y));
if(newFrame.origin.x < 0)
newFrame.origin.x = 0;
if(newFrame.origin.y < 0)
newFrame.origin.y = 0;
if(newFrame.origin.x + newFrame.size.width > self.frame.size.width)
newFrame.origin.x = self.frame.size.width - self.imageView.frame.size.width;
if(newFrame.origin.y + newFrame.size.height > self.frame.size.height)
newFrame.origin.y = self.frame.size.height - self.imageView.frame.size.height;
self.imageView.frame = newFrame;
}
}
a) You can set the clipsToBounds property of your UIView to YES
b) You can use the fallowing code for moving your UIImageView
self.imageView.center = CGPointMake(MAX(0.0, MIN(location.x - previousLocation.x, self.sub_View.bounds.size.width)), MAX(0.0, MIN(location.y - previousLocation.y, self.sub_View.bounds.size.height)));
Related
I create a touch moving event for a label which size is (30, 50). here is the code
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *superView = self.superview;
}
But I need to make sure the label can only move inside the superview. In other word, UILabel will stop moving when it “touch” the edge of view, How to setup label's moving range?
Set the label to your touch position
Check whether the label's frame is inside of the superView
If it is outside,change the frame,and set userInteractionEnabled to NO
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.center = [touches.anyObject locationInView:self.superview];
CGRect bounds = self.superview.bounds;
CGRect newFrame = self.frame;
if (newFrame.origin.x < 0) {
newFrame.origin.x = 0;
self.userInteractionEnabled = NO;
}
if (newFrame.origin.y<0) {
newFrame.origin.y = 0;
self.userInteractionEnabled = NO;
}
if (newFrame.origin.x + newFrame.size.width > bounds.size.width) {
newFrame.origin.x = bounds.size.width - newFrame.size.width;
self.userInteractionEnabled = NO;
}
if (newFrame.origin.y + newFrame.size.height > bounds.size.height) {
newFrame.origin.y = bounds.size.height - newFrame.size.height;
self.userInteractionEnabled = NO;
}
self.frame = newFrame;
}
I have an ImageView that moves around the UIView, is it possible to detect collision of the ImageView and the view its self? For example the ImageView hits the side of the view I want it to run an action. -(void)restart {}
If this is possible can you detect which side it has collided with?
You can create a custom UIImageVIew and implement the methods touchBegan and touchMoved (don't forget to add [self setUserInteractionEnabled:YES] in your init method). Then set the rect you want to interact with :
customImageView.interactRect = myView.frame;
And in your customImageView you can add something like:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
lastPosition = [touch locationInView: self.superview];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint position = [touch locationInView:self.superview];
CGRect currentFrame = self.frame;
currentFrame.origin = CGPointMake(currentFrame.origin.x + position.x - lastPosition.x, currentFrame.origin.y + position.y - lastPosition.y);
if (CGRectIntersectsRect(currentFrame, interactRect) && !CGRectIntersectsRect(self.frame, interactRect))
{
NSLog(#"I'm in for the first time");
if(self.frame.origin.x + self.frame.size.width <= interactRect.origin.x && currentFrame.origin.x + currentFrame.size.width > interactRect.origin.x)
{
NSLog(#"Coming from the left");
}
if(self.frame.origin.x >= interactRect.origin.x + interactRect.size.width && currentFrame.origin.x < interactRect.origin.x + interactRect.size.width)
{
NSLog(#"Coming from the right");
}
}
self.frame = currentFrame;
lastPosition = position;
}
I am trying to drag a UITextView object with touch ! but I have a problem , I need when user touches the custom view , the touching event begins, but touching methods works only on self.view . here is my code :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touch began ");
UITouch *touch = [touches anyObject];
startingX = [touch locationInView:_captureView].x;
startingY = [touch locationInView:_captureView].y;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint currentPoint = _mText.frame.origin;
float xForView, yForView;
UITouch *touch = [touches anyObject];
float newX = [touch locationInView:_captureView].x;
float deltaX;
if(startingX > newX){
deltaX = startingX - newX;
xForView = currentPoint.x - deltaX;
} else if(newX > startingX){
deltaX = newX - startingX;
xForView = currentPoint.x + deltaX;
} else xForView = currentPoint.x;
float newY = [touch locationInView:_captureView].y;
float deltaY;
if(startingY > newY){
deltaY = startingY - newY;
yForView = currentPoint.y - deltaY;
} else if(newY > startingY){
deltaY = newY - startingY;
yForView = currentPoint.y + deltaY;
} else yForView = currentPoint.y;
CGRect newFrame = CGRectMake(xForView, yForView, _mText.frame.size.width, _mText.frame.size.height);
_mText.frame = newFrame;
startingX = newX;
startingY = newY;
}
my textView is not editable all views are userInteractionEnabled
Write your touches began method and touches moved method inside the your custom text view and try to adjust the frame.
I have added a subview to a UIScrollView. When I zoom into the scroll view I want to pan around the subview.
In touchesBegan: I'm getting the initial location of the touch and then touchesMoved: I am able to determine how much to move the subview. It works perfectly when zoomscale is 1.0. However, when it is zoomed the pointer "breaks out" of the subview which it is intended to move (illustration here - pointer location is ilustrated as marquee tool).
The center of the view should be on pointer location, and not in it's current position! px and py variables ensure that wherever on the subview is clicked, while dragging it postion of the pointer always stays the same. illustration
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
location.x = location.x * self.zoomScale;
location.y = location.y * self.zoomScale;
px = location.x;
py = location.y;
if ([touch view] == rotateView) {
self.scrollEnabled = NO;
return;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
location.x = location.x * self.zoomScale;
location.y = location.y * self.zoomScale;
if ([touch view] == rotateView) {
rotateView.center = CGPointMake(rotateView.center.x + (location.x - px), rotateView.center.y + (location.y - py));
px = location.x;
py = location.y;
return;
}
}
Instead of the approach you're taking, make the subview another UIScrollView and let it handle the panning.
(You may wish to set scrollEnabled = NO on your subview until zooming has occurred.)
I'm trying to create a draggable image, but i'm trying to confine it's dragging to within a small square rather than the full screen. Could someone tell me where i'm going wrong?. I've placed the code that I have so far below:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if([touch view] == dot) {
CGPoint location = [touch locationInView:self.view];
dot.center = location;
if (location.x >10) {
location.x =10;
} else if (location.x <10) {
location.x = 10;
}
if (location.y >20) {
location.y =20;
} else if (location.y < 20) {
location.y = 20;
}
}
}
You are assigning location before you are making changes to it.
Apply your limits to location first then assign it to dot.
Also, your limits you are showing would lock your position to 10,20 since you are not allowing it to be more than 10 or less than 10. Likewise with 20.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if([touch view] == dot) {
CGPoint location = [touch locationInView:self.view];
location.x = MIN(MAX(location.x, 0),10);
location.y = MIN(MAX(location.y, 0),20);
dot.center = location;
}
}
I have implemented an image dragging function recently like this. I use the PAN Gesture to move the image which results in two CGFloats "endPointX and endPointY". In the code below between the comments "Stay on Screen Check" and "End Stay on Screen check", I check if these are on the screen. If not I adjust them to prevent the image moving off the screen.
I hope that helps. If you want to move the image within a small part of the total screen then I would add the image to a holder subview and then check the holder view .bounds.size.width/height above instead.
CGFloat endPointX = translatedPoint.x + (.35*[(UIPanGestureRecognizer*)sender
velocityInView:self.view].x);
CGFloat endPointY = translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);
// Stay on the screen check
if(endPointX < 0) {
endPointX = 0;
} else if(endPointX > self.view.bounds.size.width) {
endPointX = self.view.bounds.size.width;
}
if(endPointY < 0) {
endPointY = 0;
} else if(endPointY > self.view.bounds.size.height) {
endPointY = self.view.bounds.size.height;
}
// End of the Stay on Screen check
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[[sender view] setCenter:CGPointMake(endPointX, endPointY)];
[UIView commitAnimations];