Using collision on bounds of UIView - ios

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;
}

Related

Rotating a wheel?

I have read here a few examples about that, but couldn't make it work.
I have some UIView called Wheel , in which i want to rotate while touch and drag.
It should work like a real wheel, so if i touch at some point it will NOT rotate to that point, only when i drag my finger, i will get rotation .
I tried this,but i get a full rotation for every little move i do. I would like to ADD the angel to the view, not ROTATE to the new angel ..
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self];
CGPoint center=wheel.center;
float xLeg = fabs(center.x - touchPoint.x);
float yLeg = fabs(center.y-touchPoint.y);
float angle = atan(xLeg / yLeg);
NSLog(#"%f",angle);
wheel.transform = CGAffineTransformMakeRotation( angleInDegree );
}
This should do the trick. Notice how I store the first touch point in touchesBegan:withEvent:. This allows me to subtract the first touch point from every touch point I get while dragging, and thus gives me the real angle I need to rotate.
EDIT
I've done some adjustments, so that it is now smooth and regular even after several touches.
Demo
WheelViewController.m
#interface WheelViewController () {
CGPoint startPoint;
CGFloat startAngle;
CGFloat endAngle;
}
#end
#implementation WheelViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
startPoint = [touch locationInView:self.view];
startAngle = [self angleForTouchPoint:startPoint] - endAngle;
NSLog(#"\r\nStart angle: %f", startAngle);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
CGFloat touchAngle = [self angleForTouchPoint:touchPoint];
NSLog(#"Touch angle: %f", touchAngle);
self.wheel.transform = CGAffineTransformMakeRotation(fmodf(touchAngle - startAngle, 2 * M_PI));
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
endAngle = [self angleForTouchPoint:touchPoint] - startAngle;
NSLog(#"End angle: %f", endAngle);
}
- (CGFloat)angleForTouchPoint:(CGPoint)touchPoint {
CGPoint center = self.wheel.center;
float xLeg = touchPoint.x - center.x;
float yLeg = touchPoint.y - center.y;
float angle = fmodf(atan(yLeg/xLeg), (2 * M_PI));
if (xLeg < 0) {
angle += M_PI;
}
return angle;
}

Trying to move UIImageView, moving whole Screen View

I want my UIViewImages to be movable with touch. I'm trying to use code implemented in my ViewController:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count]==1) {
UITouch *touch = [touches anyObject];
CGPoint p0 = [touch previousLocationInView:self.view];
CGPoint p1 = [touch locationInView:self.view];
CGPoint center = self.view.center;
center.x += p1.x - p0.x;
center.y += p1.y - p0.y;
self.view.center = center;
}
}
When I try to drag an UIImageView, I'm dragging whole screen, which is incorrect.
Need help!
Karol
You create a gesture recognizer and add it to a view like this:
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(gestureRecognizerMethod:)];
[self.imageView addGestureRecognizer:panGestureRecognizer];
you can adjust the position of the image view
- (void)gestureRecognizerMethod:(UIPanGestureRecognizer *)recogniser
{
if (recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged)
{
CGPoint touchLocation = [recognizer locationInView:self.view];
self.imageView.center = touchLocation;
}
}
read this article.
If I read your code right self.view actually IS the whole screen.
Maybe you mean self.yourImageView instead?

TouchesMoved with UITouch

I'm trying to create a simple application where you can move your UIImageView by touching him and dragging him around.
my UIImageView is called imv
-(void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
if([touch view] == self.imv){
CGPoint location = [touch locationInView:self.view];
self.imv.center = location;
}
}
-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
if([touch view] == self.imv){
CGPoint location = [touch locationInView:self.view];
self.imv.center = location;
}
}
i'am trying to solve this like whole day and i don't know what is wrong. If i disable if statement it's working else not. What can i do?
Thanks for the answers
Unless you've subclassed UIImageView (unlikely), your view is receiving the touch events.
These days it's simpler & more usual to use a UIGestureRecognizer for this kind of thing, in this case a UIPanGestureRecognizer.
e.g.
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(dragImageView:)];
[self.imv addGestureRecognizer:pan];
- (void)dragImageView:(UIPanGestureRecognizer *)dragImageView {
if(UIGestureRecognizerStateBegan == state) {
originalCenter = self.imv.center; // add CGPoint originalCenter; member
} else if(UIGestureRecognizerStateChanged == state) {
CGPoint translate = [pan translationInView:self.imv.superview];
self.imv.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
}
}
From a bit of experimenting, it seems that the [touch view] is returning the main UIView and not your subview, hence the problem with the if statement not working (I added the UIImageView in a storyboard xib). EDIT- it's because UIImageViews don't handle touch events by default - see here . When adding a regular UIView in the viewDidLoad seems to work as you would expect.
Anyway, this adapted version of your code works for me
-(void)moveImageForTouches:(NSSet*)touches
{
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInView:self.view];
if(CGRectContainsPoint(self.imv.frame, location))
{
self.imv.center = location;
}
}
-(void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self moveImageForTouches:touches];
}
-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self moveImageForTouches:touches];
}

Panning a subview of UIScrollView after zooming in

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.)

Translate uiview in direction of touch moved, iphone

I want to translate UIView in same direction as touch moves .
Please suggest.
Modify the touchesBegan and touchesMoved methods to be like the following
float oldX, oldY;
BOOL dragging;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(window.frame, touchLocation)) {
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) {
CGRect frame = window.frame;
frame.origin.x = window.frame.origin.x + touchLocation.x - oldX;
frame.origin.y = window.frame.origin.y + touchLocation.y - oldY;
window.frame = frame;
}
oldX = touchLocation.x;
oldY = touchLocation.y;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
dragging = NO;
}
Hope it help
Try to do like the code below. I'm not sure if it is a best solution for all direction translation.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] != 1) return;
_swipeStartInX = [[touches anyObject] locationInView:self].x;
_swipeStartInY = [[touches anyObject] locationInView:self].y;
_swiping = YES;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_swiping || [touches count] != 1) return;
CGFloat swipeDistanceInX = [[touches anyObject] locationInView:self].x - _swipeStartInX;
CGFloat swipeDistanceInY = [[touches anyObject] locationInView:self].y - _swipeStartInY;
CGSize contentSize = self.frame.size;
[_yourView setFrame:CGRectMake(swipeDistanceInX - contentSize.width, swipeDistanceInY - contentSize.width, contentSize.width, contentSize.height)];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_swiping) return;
// You can set the last position when touches end.
// E.g. You can set positions like slide page does, just the the origin of _yourView.
}
If you just want translate in vertical and horizontal direction, you can use UIScrolView instead. :)
You can just add this method to your subclassed UIView class.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint currentLocation = [touch locationInView:self];
CGPoint previousLocation= [touch previousLocationInView:self];
CGFloat deltaX = currentLocation.x - previousLocation.x;
CGFloat deltaY = currentLocation.y - previousLocation.y;
self.frame = CGRectMake(self.frame.origin.x + deltaX, self.frame.origin.y + deltaY, self.frame.size.width, self.frame.size.height);
}

Resources