I am trying to create four touchable and movable labels on a UIView.
When I touch a ifAnimaPart01 somehow they are all gathered in one location and I can not touch or move the other labels.
Does anyone know why my four labels are acting this way?
I added another 4 labels to display the x and y coordinates for debugging.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if ([touch view] == ifAnimPart01){
ifAnimPart01.center = location;
}
else if ([touch view] == ifAnimPart02){
ifAnimPart02.center= location;
}
else if ([touch view] == ifAnimPart03){
ifAnimPart03.center= location;
}
else if ([touch view] == ifAnimPart04){
ifAnimPart04.center= location;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[self touchesBegan:touches withEvent:event];
UITouch *myTouch = [touches anyObject];
startPoint1 = [myTouch locationInView:self.view];
xCoordLabel1.text = [NSString stringWithFormat:#"Line OneX = %f", startPoint1.x];
yCoordLabel1.text = [NSString stringWithFormat:#"Line OneY = %f", startPoint1.y];
ifAnimPart01.center = CGPointMake(startPoint1.x, startPoint1.y);
startPoint2 = [myTouch locationInView:self.view];
xCoordLabel2.text = [NSString stringWithFormat:#"Line TwoX = %f", startPoint2.x];
yCoordLabel2.text = [NSString stringWithFormat:#"Line TwoY = %f", startPoint2.y];
ifAnimPart02.center = CGPointMake(startPoint2.x, startPoint2.y);
startPoint3 = [myTouch locationInView:self.view];
xCoordLabel3.text = [NSString stringWithFormat:#"Line ThreeX = %f", startPoint3.x];
yCoordLabel3.text = [NSString stringWithFormat:#"Line ThreeY = %f", startPoint3.y];
ifAnimPart03.center = CGPointMake(startPoint3.x, startPoint3.y);
startPoint4 = [myTouch locationInView:self.view];
xCoordLabel4.text = [NSString stringWithFormat:#"Line FourX = %f", startPoint4.x];
yCoordLabel4.text = [NSString stringWithFormat:#"Line FourY = %f", startPoint4.y];
ifAnimPart04.center = CGPointMake(startPoint4.x, startPoint4.y);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
}
Related
In the image below, I draw and the result is at point A, right where my finger touches.
How can I make the image appear about 40pt above my actual touch. (B)
I'm using the classic coreGraphic UITouch code, like so:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// add the first touch
UITouch *touch = [touches anyObject];
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
//transform = CGAffineTransformTranslate(self.transform, 5.0, 10.0)
// init the bezier path
self.currentTool = [self toolWithCurrentSettings];
self.currentTool.lineWidth = self.lineWidth;
self.currentTool.lineColor = self.lineColor;
self.currentTool.lineAlpha = self.lineAlpha;
[self.pathArray addObject:self.currentTool];
[self.undoStates addObject:[self.currentTool captureToolState]];
[self.currentTool setInitialPoint:currentPoint];
}
// call the delegate
if ([self.delegate respondsToSelector:#selector(drawingView:willBeginDrawUsingTool:)]) {
[self.delegate drawingView:self willBeginDrawUsingTool:self.currentTool];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// save all the touches in the path
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
[self.currentTool moveFromPoint:previousPoint1 toPoint:currentPoint];
[self setNeedsDisplay];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// make sure a point is recorded
[self touchesMoved:touches withEvent:event];
CGPoint point = [[touches anyObject] locationInView:self];
[self.currentTool setInitialPoint:point];
self.draggableTextView = ((ACEDrawingDraggableTextTool *)self.currentTool).labelView;
[self.pathArray addObject:self.currentTool];
[self finishDrawing];
[self finishDrawing];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// make sure a point is recorded
[self touchesEnded:touches withEvent:event];
}
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
// add these 2 lines below:
previousPoint1 = CGPointMake(previousPoint1.x, previousPoint1.y+40);
currentPoint = CGPointMake(currentPoint.x, currentPoint.y+40);
The game I'm trying to make is simple enough. A UIImageView fireball falls from the top of the screen, and the touch screen is used to move the other UIImageView Dustin to avoid it.
Once the fireball reaches the bottom of the screen, it resets back to the top, and the user's score increases by 1. The problem is that after I added the scoring functions, the Dustin UIImage resets to its original position after the fireball reaches the bottom. Without the scoring method, Dustin's image doesn't reset. How does the scoring cause my imageview's position to reset? Most of my code from the ViewController is below.
int theScore;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initializeTimer];
}
- (void)updateScore {
theScore = theScore + 1;
_score.text = [[NSString alloc] initWithFormat:#"%d",theScore];
}
- (void) initializeTimer {
if(theTimer == nil)
{
theTimer = [CADisplayLink displayLinkWithTarget:self selector:#selector(gameLogic:)];
}
theTimer.frameInterval = 1;
[theTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void) gameLogic:(CADisplayLink *) theTimer {
if(!CGRectIntersectsRect(_fireball.frame, _Dustin.frame)){
if(_fireball.center.y >600){
_fireball.center = CGPointMake(0, 0);
[self updateScore];
}
_fireball.center = CGPointMake(_fireball.center.x, _fireball.center.y+4);
}
else{
}
}
- (void) touchesBegan:(NSSet *) touches withEvent:(UIEvent *) event {
UITouch *touch = [touches anyObject];
_firstTouch = [touch locationInView:self.view];
_lastTouch = [touch locationInView:self.view];
_Dustin.center = CGPointMake(_firstTouch.x, _Dustin.center.y);
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
_firstTouch = [touch locationInView:self.view];
_lastTouch = [touch locationInView:self.view];
_Dustin.center = CGPointMake(_firstTouch.x, _Dustin.center.y);
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
_firstTouch = [touch locationInView:self.view];
_lastTouch = [touch locationInView:self.view];
_Dustin.center = CGPointMake(_firstTouch.x, _Dustin.center.y);
}
UPDATE
I have solved the problem with following code:
- (BOOL) isInside:(NSSet *)touches
{
//NSLog(#"%s", __PRETTY_FUNCTION__);
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
BOOL isInside = NO;
//NSLog(#"touchLocation %#", NSStringFromCGPoint(touchLocation) );
//NSLog(#"self.position %#", NSStringFromCGPoint(self.position) );
//NSLog(#"self.frame %#", NSStringFromCGRect(self.frame) );
//NSLog(#"self.size %#", NSStringFromCGSize(self.size) );
CGFloat atlX = fabsf(touchLocation.x);
CGFloat atlY = fabsf(touchLocation.y);
CGFloat lenX = self.size.width / 2;
CGFloat lenY = self.size.height / 2;
if ( (atlX <= lenX) && (atlY <= lenY) ) {
isInside = YES;
}
return isInside;
}
Original Question
This code I used for my subclass of UIView:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self];
BOOL isInside = [self pointInside:touchLocation withEvent:event];
if (isInside)
{
if (NO == _isAlreadySelected)
{
[self setAppearanceSelected];
}
else
{
[self removeAppearanceSelected];
}
// more code
}
}
Now I have class that is subclass of SKSpriteNode, so I wanted to use same logic:
CGPoint touchLocation = [touch locationInView:self];
BOOL isInside = [self pointInside:touchLocation withEvent:event];
But it is not working, I can not compile. (because these method do not exist for SKSpriteNode).
I manage to change first line to:
CGPoint touchLocation = [touch locationInNode:self];
Question
But how to fix:
BOOL isInside = [self pointInside:touchLocation withEvent:event];
for SKSpriteNode
UPDATE
Current solution with help from #duci9y
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"%s", __PRETTY_FUNCTION__);
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
BOOL isInside = [self containsPoint:touchLocation];
NSLog(#"touchLocation %#", NSStringFromCGPoint(touchLocation) );
NSLog(#"self.position %#", NSStringFromCGPoint(self.position) );
NSLog(#"self.frame %#", NSStringFromCGRect(self.frame) );
if (isInside)
{
NSLog(#"INSIDE");
//self.texture = [SKTexture textureWithImage:_onImage];
}
else
{
NSLog(#"OUTSIDE");
//self.texture = [SKTexture textureWithImage:_offImage];
}
}
LOGS:
-[WOC_OnOffImageButton touchesBegan:withEvent:]
touchLocation {9.5, 18}
self.position {160, 440}
self.frame {{138, 414.5}, {44, 51}}
OUTSIDE
To me it look like that there is some problem with coordinate system between SpriteKit and UIView. e.g. they do not start from same point (bottom-left vs. top-left).
Read the docs.
BOOL isInside = [self containsPoint:touchLocation];
I want to make sure that the motion moved with the button held down picture (as in some trategiyah). But the image shake when I move it. Here's the code:
// PROPERTY
#property (nonatomic, retain) UIView *gameView;
#property GameState gameState; // for current state == Game
#property CGPoint touchPoint;
#property CGPoint screenOffset;
// INICIALIZE
_gameView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIGraphicsBeginImageContext(_gameView.frame.size);
[[UIImage imageNamed:iname] drawInRect:_gameView.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_gameView.backgroundColor = [UIColor colorWithPatternImage:image];
_gameView.userInteractionEnabled = YES;
[self.view addSubview:_gameView];
// METHODS
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
switch (_gameState) {
case Start:
break;
case Game:
if ([touch view] == _gameView) {
_touchPoint = [touch locationInView:touch.view];
NSLog(#"startTouch");
}
break;
default:
break;
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint currentTouchPoint = [touch locationInView:touch.view];
switch (_gameState) {
case Start:
break;
case Game:
if ([touch view] == _gameView) {
NSLog(#"%f%f", [touch locationInView:touch.view].x, [touch locationInView:touch.view].y);
currentTouchPoint.x += _screenOffset.x - _touchPoint.x;
currentTouchPoint.y += _screenOffset.y - _touchPoint.y;
_gameView.center = currentTouchPoint;
}
break;
default:
break;
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint endedTouchPoint = [touch locationInView:touch.view];
switch (_gameState) {
case Start:
break;
case Game:
if ([touch view] == _gameView) {
_screenOffset.x += endedTouchPoint.x - _touchPoint.x;
_screenOffset.y += endedTouchPoint.y - _touchPoint.y;
_gameView.center = _screenOffset;
NSLog(#"endTouch");
}
break;
default:
break;
}
}
Even if slightly moving the mouse - the image jumps. Here is what appears in the log:
startTouch
206.000000 319.000000
206.000000 338.000000
209.000000 342.000000
211.000000 367.000000
217.000000 393.000000
228.000000 435.000000
291.000000 580.000000
244.000000 470.000000
316.000000 620.000000
250.000000 470.000000
330.000000 620.000000
263.000000 468.000000
...
endTouch
At the same time I moved the pointer one direction. Where mistake?
I not want to move all objects.
I find reason. If write:
_gameView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"field1.png"]];
_gameView.frame = [[UIScreen mainScreen] bounds];
//_gameView.userInteractionEnabled = YES;
that's work, but if uncomment last string problem return. But it needs for my program =(
You can make sure the location of the touch is given in coordinates of AddView's parent view with the line:
CGPoint location = [touch locationInView:AddView.superview];
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);
}