I used codes below to detect the touch on UIImage
//
#import <UIKit/UIKit.h>
#interface KUIImageView : UIImageView
{
CGPoint startLocation;
}
#end
#implementation KUIImageView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
// Retrieve the touch point
CGPoint pt = [[touches anyObject] locationInView:self];
startLocation = pt;
[[self superview] bringSubviewToFront:self];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
// Move relative to the original touch point
CGPoint pt = [[touches anyObject] locationInView:self];
CGRect frame = [self frame];
frame.origin.x += pt.x - startLocation.x;
frame.origin.y += pt.y - startLocation.y;
[self setFrame:frame];
}
#end
I set the breakpoint at touchesBegan
But it was not triggered
the UIImage was on a UIScrollView by using
[aScrollView addObject:aUIImageView];
Welcome any comment
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// here
self.userInteractionEnabled = YES;
}
return self;
}
Related
How to add a magnifier to custom control? Control is a child of UIView. (It's a UIWebView - but native magnification functionality doesn't work at some pages.)
UPDATED:
Maybe it's possible to force a draw of magnifier on UIWebView?
1. Add the following files to your project:
MagnifierView.h:
//
// MagnifierView.h
// SimplerMaskTest
//
#import <UIKit/UIKit.h>
#interface MagnifierView : UIView {
UIView *viewToMagnify;
CGPoint touchPoint;
}
#property (nonatomic, retain) UIView *viewToMagnify;
#property (assign) CGPoint touchPoint;
#end
MagnifierView.m:
//
// MagnifierView.m
// SimplerMaskTest
//
#import "MagnifierView.h"
#import <QuartzCore/QuartzCore.h>
#implementation MagnifierView
#synthesize viewToMagnify;
#dynamic touchPoint;
- (id)initWithFrame:(CGRect)frame {
return [self initWithFrame:frame radius:118];
}
- (id)initWithFrame:(CGRect)frame radius:(int)r {
int radius = r;
if ((self = [super initWithFrame:CGRectMake(0, 0, radius, radius)])) {
//Make the layer circular.
self.layer.cornerRadius = radius / 2;
self.layer.masksToBounds = YES;
}
return self;
}
- (void)setTouchPoint:(CGPoint)pt {
touchPoint = pt;
// whenever touchPoint is set, update the position of the magnifier (to just above what's being magnified)
self.center = CGPointMake(pt.x, pt.y-66);
}
- (CGPoint)getTouchPoint {
return touchPoint;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect bounds = self.bounds;
CGImageRef mask = [UIImage imageNamed: #"loupe-mask#2x.png"].CGImage;
UIImage *glass = [UIImage imageNamed: #"loupe-hi#2x.png"];
CGContextSaveGState(context);
CGContextClipToMask(context, bounds, mask);
CGContextFillRect(context, bounds);
CGContextScaleCTM(context, 1.2, 1.2);
//draw your subject view here
CGContextTranslateCTM(context,1*(self.frame.size.width*0.5),1*(self.frame.size.height*0.5));
//CGContextScaleCTM(context, 1.5, 1.5);
CGContextTranslateCTM(context,-1*(touchPoint.x),-1*(touchPoint.y));
[self.viewToMagnify.layer renderInContext:context];
CGContextRestoreGState(context);
[glass drawInRect: bounds];
}
- (void)dealloc {
[viewToMagnify release];
[super dealloc];
}
#end
TouchReader.h:
//
// TouchReader.h
// SimplerMaskTest
//
#import <UIKit/UIKit.h>
#import "MagnifierView.h"
#interface TouchReader : UIView {
NSTimer *touchTimer;
MagnifierView *loop;
}
#property (nonatomic, retain) NSTimer *touchTimer;
- (void)addLoop;
- (void)handleAction:(id)timerObj;
#end
TouchReader.m:
//
// TouchReader.m
// SimplerMaskTest
//
#import "TouchReader.h"
#import "MagnifierView.h"
#implementation TouchReader
#synthesize touchTimer;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.touchTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(addLoop) userInfo:nil repeats:NO];
// just create one loop and re-use it.
if (loop == nil) {
loop = [[MagnifierView alloc] init];
loop.viewToMagnify = self;
}
UITouch *touch = [touches anyObject];
loop.touchPoint = [touch locationInView:self];
[loop setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleAction:touches];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.touchTimer invalidate];
self.touchTimer = nil;
[loop removeFromSuperview];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self.touchTimer invalidate];
self.touchTimer = nil;
[loop removeFromSuperview];
}
- (void)addLoop {
// add the loop to the superview. if we add it to the view it magnifies, it'll magnify itself!
[self.superview addSubview:loop];
// here, we could do some nice animation instead of just adding the subview...
}
- (void)handleAction:(id)timerObj {
NSSet *touches = timerObj;
UITouch *touch = [touches anyObject];
loop.touchPoint = [touch locationInView:self];
[loop setNeedsDisplay];
}
- (void)dealloc {
[loop release];
loop = nil;
[super dealloc];
}
#end
Based on: http://coffeeshopped.com/2010/03/a-simpler-magnifying-glass-loupe-view-for-the-iphone
2. Add the following images:
Used images on the code:
loupe-hi#2x.png:
loupe-mask#2x.png:
Original but centered images with a shadow (not used at this moment):
loupe-shadow-hi#2x.png:
loupe-shadow-mask#2x.png:
3. Replace the main UIView on your xib-file by TouchReader
The magnifier will work automaticaly except controls that captures touch events themselfs (for example, UIWebView). And the code above doesn't support the images with a shadow. Please add new answer to the qustion if you successfully fix this issue.
UPDATED:
Change the following code to add UIWebView support. UIView should remain UIView.
#interface TouchReader : UILongPressGestureRecognizer
And add a gesture to webView:
TouchReader* gestureMagnifier = [[[TouchReader alloc] initWithTarget:self action:#selector(handleMagnifier:)] autorelease];
gestureMagnifier.webView = editSource;
gestureMagnifier.delegate = self;
gestureMagnifier.minimumPressDuration = 0.5;
[webView addGestureRecognizer:gestureMagnifier];
TouchReader.h:
//- (void)handleAction:(id)timerObj;
-(void) handleGestureAction:(CGPoint)location;
TouchReader.m:
-(void)awakeFromNib
{
UILongPressGestureRecognizer * longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[self addGestureRecognizer:longPressGesture];
}
-(void)handleGesture:(UILongPressGestureRecognizer *)longPressGesture
{
CGPoint location = [longPressGesture locationInView:self];
switch (longPressGesture.state) {
case UIGestureRecognizerStateBegan:
self.touchTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(addLoop)
userInfo:nil
repeats:NO];
// just create one loop and re-use it.
if(loop == nil){
loop = [[MagnifierView alloc] init];
loop.viewToMagnify = self;
}
loop.touchPoint = location;
[loop setNeedsDisplay];
break;
case UIGestureRecognizerStateChanged:
[self handleGestureAction:location];
break;
case UIGestureRecognizerStateEnded:
[self.touchTimer invalidate];
self.touchTimer = nil;
[loop removeFromSuperview];
loop=nil;
break;
default:
break;
}
}
- (void)addLoop {
// add the loop to the superview. if we add it to the view it magnifies, it'll magnify itself!
[self.superview addSubview:loop];
}
-(void) handleGestureAction:(CGPoint)location
{
loop.touchPoint = location;
[loop setNeedsDisplay];
}
You don't need the touches... methods any more.
i am using ktphotobrowser for my app. in big image screen (ktphotoscrollviewcontroller) when i zoom image with two times tapping, the content size of scrollview (ktphotoview - it is an uiscrollview object) grows to bound.size * maximumzoomscale but my zoomed image size still smaller than contentsize of scrollview. both zoomed image size and the scrollview's contentsize must be same so where can i do these calculation on the code?
if anybody use ktphotobrowser could help me about this problem, i will very appreciate.
i find the tap count but after this code i couldnt find where is the contentsize growing (zoom) or image growing (zoom) code
below you can find the whole code of ktphotoview.h page where the tapping count and zooming actions are coded:
#import "KTPhotoView.h"
#import "KTPhotoScrollViewController.h"
#import <QuartzCore/QuartzCore.h>
#interface KTPhotoView (KTPrivateMethods)
- (void)loadSubviewsWithFrame:(CGRect)frame;
- (BOOL)isZoomed;
- (void)toggleChromeDisplay;
#end
#implementation KTPhotoView
#synthesize scroller = scroller_;
#synthesize index = index_;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setDelegate:self];
[self setMaximumZoomScale:2.0];
[self setShowsHorizontalScrollIndicator:NO];
[self setShowsVerticalScrollIndicator:NO];
[self loadSubviewsWithFrame:frame];
NSLog(#"scrollview2 %f",self.contentSize.height);
}
return self;
}
- (void)loadSubviewsWithFrame:(CGRect)frame
{
imageView_ = [[UIImageView alloc] initWithFrame:frame];
[imageView_ setContentMode:UIViewContentModeScaleAspectFit];
[self addSubview:imageView_];
}
- (void)setImage:(UIImage *)newImage
{
[imageView_ setImage:newImage];
}
- (void)layoutSubviews
{
[super layoutSubviews];
if ([self isZoomed] == NO && CGRectEqualToRect([self bounds], [imageView_ frame]) == NO) {
[imageView_ setFrame:[self bounds]];
}
}
- (void)toggleChromeDisplay
{
if (scroller_) {
[scroller_ toggleChromeDisplay];
}
}
- (BOOL)isZoomed
{
return !([self zoomScale] == [self minimumZoomScale]);
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [self frame].size.height / scale;
zoomRect.size.width = [self frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
NSLog(#"zoomRectHeight %f",[self frame].size.height);
return zoomRect;
}
- (void)zoomToLocation:(CGPoint)location
{
float newScale;
CGRect zoomRect;
if ([self isZoomed]) {
zoomRect = [self bounds];
} else {
newScale = [self maximumZoomScale];
zoomRect = [self zoomRectForScale:newScale withCenter:location];
}
// NSLog(#"zoomRectHeight %f",location.);
[self zoomToRect:zoomRect animated:YES];
}
- (void)turnOffZoom
{
if ([self isZoomed]) {
[self zoomToLocation:CGPointZero];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self) {
if ([touch tapCount] == 2) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(toggleChromeDisplay) object:nil];
[self zoomToLocation:[touch locationInView:self]];
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self) {
if ([touch tapCount] == 1) {
[self performSelector:#selector(toggleChromeDisplay) withObject:nil afterDelay:0.5];
}
}
}
#pragma mark -
#pragma mark UIScrollViewDelegate Methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
UIView *viewToZoom = imageView_;
NSLog(#"scrollview %f",self.contentSize.height);
return viewToZoom;
}
i use the below code in ktphotoview.m file to solve my problem hope this helps:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self) {
if ([touch tapCount] == 2) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(toggleChromeDisplay) object:nil];
[self zoomToRect:[self zoomRectForScale:[self maximumZoomScale] withCenter:[touch locationInView:self]] animated:YES];
float abc=(self.contentSize.height-(imageView_.image.size.height*320/imageView_.image.size.width*self.maximumZoomScale))/2 *-1;
[self setContentInset:UIEdgeInsetsMake(abc, 0, abc, 0)];
}
}
}
I'm trying to achieve a Drag and Drop menu affect. I'm not sure how to go about this, perhaps someone has experience with this exact effect.
Quite simply, when a user touches down on a menu item, I want a graphic to appear at their touch location. Their touch will now control the panning of the graphic. Upon releasing the touch, the graphic will sit in its place and assume full alpha.
I'm already familiar with creating pan gestures and instantiating a graphic. So far, I can create the graphic where the menu item is touched. The biggest issue is how I "pass over" the touch gesture so it is a single and continuous motion.
Also, should the menu item be UIButton or UIImageView?
Any help appreciated. Thanks
I had some fun with this one. The following code will grab the image from the button when touched, drag that image at alpha=0.5, and drop it wherever your touches end at alpha=1.0. It will continue to be draggable thereafter.
After importing QuartzCore, create a new file. The .h should read:
#import <Foundation/Foundation.h>
#import <QuartzCore/CAGradientLayer.h>
#import <QuartzCore/CALayer.h>
#interface DraggableImage : CAGradientLayer
- (void)draw:(UIImage *)image;
- (void)moveToFront;
- (void)appearDraggable;
- (void)appearNormal;
#end
and the .m should read:
#import "DraggableImage.h"
#implementation DraggableImage
- (void)draw:(UIImage *)image{
CGRect buttonFrame = self.bounds;
int buttonWidth = buttonFrame.size.width;
int buttonHeight = buttonFrame.size.height;
UIGraphicsBeginImageContext( CGSizeMake(buttonWidth, buttonHeight) );
[image drawInRect:self.bounds];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[newImage drawInRect:self.bounds];
}
- (void)moveToFront {
CALayer *superlayer = self.superlayer;
[self removeFromSuperlayer];
[superlayer addSublayer:self];
}
- (void)appearDraggable {
self.opacity = 0.5;
}
- (void)appearNormal {
self.opacity = 1.0;
}
#end
Now in your main view controller, add:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "DraggableImage.h"
#interface YourViewController : UIViewController{
DraggableImage *heldImage;
DraggableImage *imageForFrame[5]; // or however many
UIButton *buttonPressed;
int imageCount;
}
#property (weak, nonatomic) IBOutlet UIButton *imageButton;
-(IBAction)buildImageLayerForButton:(UIButton *)sender;
- (void)moveHeldImageToPoint:(CGPoint)location;
- (CALayer *)layerForTouch:(UITouch *)touch;
The imageButton in this case would be your apple Button. Now in your .m file, add this:
#synthesize imageButton;
#pragma - mark Touches
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CALayer *hitLayer = [self layerForTouch:[touches anyObject]];
if ([hitLayer isKindOfClass:[DraggableImage class]]) {
DraggableImage *image = (DraggableImage *)hitLayer;
heldImage = image;
[heldImage moveToFront];
}
hitLayer = nil;
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if (heldImage)
{
UITouch *touch = [touches anyObject];
UIView *view = self.view;
CGPoint location = [touch locationInView:view];
[self moveHeldImageToPoint:location];
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
if (heldImage) {
[heldImage appearNormal];
heldImage = nil;
}
}
- (void)dragBegan:(UIControl *)c withEvent:ev {
}
- (void)dragMoving:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
[self moveHeldImageToPoint:touchPoint];
}
- (void)dragEnded:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
[self moveHeldImageToPoint:touchPoint];
[heldImage appearNormal];
heldImage = nil;
}
-(IBAction)buildImageLayerForButton:(UIButton *)sender{
DraggableImage *image = [[DraggableImage alloc] init];
buttonPressed = sender;
CGRect buttonFrame = sender.bounds;
int buttonWidth = buttonFrame.size.width;
int buttonHeight = buttonFrame.size.height;
image.frame = CGRectMake(120, 24, buttonWidth*3, buttonHeight*3);
image.backgroundColor = [UIColor lightGrayColor].CGColor;
image.delegate = self;
imageForFrame[imageCount] = image;
[self.view.layer addSublayer:image];
[image setNeedsDisplay];
[image moveToFront];
[image appearDraggable];
heldImage = image;
[self moveHeldImageToPoint:sender.center];
imageCount++;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
UIGraphicsPushContext(ctx);
DraggableImage *image = (DraggableImage *)layer;
[image draw:[buttonPressed imageForState:UIControlStateNormal]];
UIGraphicsPopContext();
}
- (void)moveHeldImageToPoint:(CGPoint)location
{
float dx = location.x;
float dy = location.y;
CGPoint newPosition = CGPointMake(dx, dy);
[CATransaction begin];
[CATransaction setDisableActions:TRUE];
heldImage.position = newPosition;
[CATransaction commit];
}
- (CALayer *)layerForTouch:(UITouch *)touch
{
UIView *view = self.view;
CGPoint location = [touch locationInView:view];
location = [view convertPoint:location toView:nil];
CALayer *hitPresentationLayer = [view.layer.presentationLayer hitTest:location];
if (hitPresentationLayer)
{
return hitPresentationLayer.modelLayer;
}
return nil;
}
-(void)viewDidLoad{
[imageButton addTarget:self action:#selector(dragBegan:withEvent:) forControlEvents: UIControlEventTouchDown];
[imageButton addTarget:self action:#selector(dragMoving:withEvent:) forControlEvents: UIControlEventTouchDragInside | UIControlEventTouchDragOutside];
[imageButton addTarget:self action:#selector(dragEnded:withEvent:) forControlEvents: UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
[super viewDidLoad];
}
- (void)viewDidUnload {
[self setImageButton:nil];
[super viewDidUnload];
}
Et voila! Connect your button, set its image, and throw copies all over the screen. :)
Note: I didn't comment much, but would be happy to answer any questions.
Cheers!
EDIT: fixed the -(void)draw:(UIImage *)image{} so that it would resize the image properly.
if what you want is to pass the touch function to the second graphic (the big one) i think you can do something like this
on .h you have to declare the images that you're going to drag and float variable to remember previous point of the dragable button (i'm assuming you use IOS 5 SDK)
#property(nonatomic, strong) UIImageView* myImage;
#property float pointX;
#property float pointY;
then, at .m you can do this
myImage = [[UIImageView alloc]initWithImage:#"appleImage.jpg"];
myImage.alpha = 0;
//default UIImageView interaction is disabled, so lets enabled it first
myImage.userInteractionEnabled = YES;
[button addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
and then make the drag function
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
self.myImage.alpha = 0.5;
UITouch *touch = [[event touchesForView:button] anyObject];
CGPoint previousLocation = [touch previousLocationInView:button];
CGPoint location = [touch locationInView:button];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button, to keep the dragging effect
button.center = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
// moving the image
button.center = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
self.pointX = previousLocation.x;
self.pointY = previousLocation.y;
[button addTarget:self action:#selector(dragRelease:withEvent:) forControlEvents:UIControlEventTouchUpInside];
}
finally, make the dragRelease function where you return the button to its original place and set the alpha of the images to 1
-(void)dragRelease:(UIButton *)button withEvent:(UIEvent *)event
{
self.myImage.alpha = 1;
button.center = CGPointMake(pointX, pointY);
}
and you're done :3
this is just the basic idea though, maybe this isn't what you want, but i hope this helps
edit* : oh and don't forget to synthesize all the properties, also if you're using SDK below 5.0, you can change the "strong" property to "retain"
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Drawing on the iPhone in objective c
I have written this...
In the .h file:
#import <UIKit/UIKit.h>
#interface DrawView : UIView {
CGPoint gestureStartPoint,currentPosition;
CGContextRef c;
UIBezierPath *currentPath;
}
#property(nonatomic,retain)UIBezierPath *currentPath;
#end
And in the .m file:
#import "DrawView.h"
#implementation DrawView
#synthesize currentPath;
- (id)initWithFrame:(CGRect)frame {
[self drawRect:CGRectMake(0, 0, 320, 480)];
self = [super initWithFrame:frame];
if (self) {
currentPath = [[UIBezierPath alloc]init];
currentPath.lineWidth=3;
}
return self;
}
- (void)drawRect:(CGRect)rect {
[[UIColor redColor] set];
[currentPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
currentPosition = [touch locationInView:self];
[currentPath addLineToPoint:(currentPosition)];
[self setNeedsDisplay];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
gestureStartPoint = [touch locationInView:self];
[currentPath moveToPoint:(gestureStartPoint)];
}
- (void)dealloc {
[super dealloc];
}
#end
I want to let the user draw an image on the iPhone screen and then use that image for the game... but this doesn't draw anything...
This is because your currentPath is not allocated.
If you instantiate the view in the resource [UIView initWithFrame:] will never be called.
Implement [UIView initWithCoder:] and allocate it there.
- (void)commonInit
{
currentPath = [[UIBezierPath alloc] init];
currentPath.lineWidth=3;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self commonInit];
}
return self;
}
- (id)initWithCoder:(NSCoder*)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self commonInit];
}
return self;
}
Alternatively you can make the path in the touchesBegan if it is nil.
- (UIBezierPath*)currentPath
{
if (currentPath = nil)
{
currentPath = [[UIBezierPath alloc] init];
currentPath.lineWidth=3;
}
return currentPath;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
gestureStartPoint = [touch locationInView:self];
[[self currentPath] moveToPoint:(gestureStartPoint)];
}
However, there are some problems in the code.
You call [self drawRect:CGRectMake(0, 0, 320, 480)] before self = [super initWithFrame:frame]. You must not call any method there. You can write your code only inside
if (self ! =nil)
{
// your code
}
currentPath leaks. Release it in dealloc.
Never call drawRect directly. Call [UIView setNeedsDisplay] instead.
I have an sprite the I need to rotate it with touch but it is located in a different layer. Is it possible to update it's position?
E.G.
Sprite has it's own layer but it's position needs to be updated within the main gamescene
here is what I have so far.
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "GameScene.h"
#interface G : CCLayer {
CCSprite *g;
CGFloat gRotation;
}
#end
------------------------------------------
#import "G.h"
#implementation G
-(id) init
{
if ((self = [super init]))
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
g = [CCSprite spriteWithFile:#"g.png"];
[self addChild:g z:-1];
//[self scheduleUpdate];
if (g.rotation == 360)
{
[self unscheduleUpdate];
}
}
return self;
}
- (void)update:(ccTime)delta
{
g.rotation = gRotation;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint firstLocation = [touch previousLocationInView:[touch view]];
CGPoint location = [touch locationInView:[touch view]];
CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];
CGPoint firstVector = ccpSub(firstTouchingPoint, g.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, g.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
gRotation += currentTouch - previousTouch;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void) dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[super dealloc];
}
#end
GameScene
#import "GameScene.h"
#import "MainMenu.h"
#import "G.h"
#implementation GameScene
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
GameScene *layer = [GameScene node];
[scene addChild: layer];
return scene;
}
-(void) tapG: (id) sender
{
G *gView;
gView = [[G alloc] init];
gView.position = ccp(100, 100);
[self.parent addChild:gView z:1001];
[gView schedule:#selector(update:)];
[gView release];
}
-(id) init
{
if ((self = [super init]))
{
tG = [CCMenuItemImage itemFromNormalImage:#"tp.png" selectedImage:#"tp.png" disabledImage:#"tpaperd.png" target:self selector:#selector(tapG:)];
gt = [CCMenu menuWithItems:tG, nil];
gt.position = ccp(210, 80);
[gt alignItemsHorizontallyWithPadding:10];
[self addChild:gt z:0];
}
return self;
}
- (void) dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[super dealloc];
}
It brings up the sprite but the sprite does not rotate.
you can schedule updates for another layer.
are you sure your G layer is set to be touch enabled? try gView.isTouchEnabled = YES; after allocating gView. you may need to confirm to the protocol. Add <CCStandardTouchDelegate> to your CCLayer interface: #interface G : CCLayer <CCStandardTouchDelegate> { ....
also you can schedule -(void)update:(ccTime)delta method using [gView scheduleUpdate]; it will give the same result but its more convenient.