Drag image from scrollview to view without compromising its location - image

How can I make sure that the images that are within my scroller will be able to be dragged from the scroller to the imageview?
I also would like to implement a 'wiggle'. When a user taps an image within the scroller the images wiggles and follows the touch of the user to the other view. I started with making a subview, however when the image displays itself on the normal view its location changes to be on top of the view instead of on the bottom.
How can I make sure that when I touch an image:
the image wiggles
the images go to another view.
the images follow my touch position
(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
image1.userInteractionEnabled = YES;
[self.view addSubview:image1];
if([touch view] == image1){
image1.center = location;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.14];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:1000000];
image1.transform = CGAffineTransformMakeRotation(69);
image1.transform = CGAffineTransformMakeRotation(-69);
[UIView commitAnimations];
image1.center = CGPointMake(30,870);
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *) event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if([touch view] == image1){
image1.userInteractionEnabled = YES;
[self.view addSubview:image1];
image1.center = location;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.14];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:1000000];
image1.transform = CGAffineTransformMakeRotation(69);
image1.transform = CGAffineTransformMakeRotation(-69);
[UIView commitAnimations];
}

In stead of using the 'touches functions' I used gestureRecognizers. You can put a recognizer on a certain image (TapRecognizer of LongpressRecognizer). When a user presses the image the App recognizes the touch. Afterwords you can put the image in a subview on top of your normal view with the function "[self.view addSubview:yourImage];"
Here's a snippit
First you declare the gesturerecognizer in your viewDidLoad, viewDidAppear or viewWillappear method
UILongPressGestureRecognizer *longPress =
[[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressed:)];
longPress.minimumPressDuration = 0.7;
[yourimage addGestureRecognizer:longPress1];
Afterwords you use the delegate function
-(void)longPressed:(UILongPressGestureRecognizer *)sender {
CGPoint location = [sender locationInView:self.view];
[self.view addSubview:yourimage];
yourimage.center = location;
//perform a transform (wiggle or scale)
if([(UILongPressGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
yourimage.transform = CGAffineTransformMakeScale(1.0, 1.0);
//stop the transform
}
}
Hope this helps you out Elppa

Related

drawRect not called on PDFView subclass

I have a custom PDFView subclass and have overridden -mouseDown, -mouseDragged etc to draw a rectangle over the view. Here is the code I am using:
#implementation MyPDFView {
NSPoint clickLocation;
NSRect selection;
}
- (void)mouseDown:(NSEvent *)theEvent {
NSPoint clickLocationOnWindow = [self.window mouseLocationOutsideOfEventStream];
clickLocation = [self convertPoint:clickLocationOnWindow fromView:nil];
NSLog(#"%#", NSStringFromPoint(clickLocation));
}
- (void)mouseDragged:(NSEvent *)theEvent {
NSPoint mouseLocationOnWindow = [self.window mouseLocationOutsideOfEventStream];
NSPoint currentLocation = [self convertPoint:mouseLocationOnWindow fromView:nil];
CGFloat lowerX = fmin(clickLocation.x, currentLocation.x);
CGFloat lowerY = fmin(clickLocation.y, currentLocation.y);
CGFloat upperX = fmax(clickLocation.x, currentLocation.x);
CGFloat upperY = fmax(clickLocation.y, currentLocation.y);
selection = NSMakeRect(lowerX, lowerY, upperX-lowerX, upperY-lowerY);
[self setNeedsDisplay:YES];
NSLog(#"%#", NSStringFromRect(selection));
}
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
NSLog(#"drawRect");
NSBezierPath *bp = [NSBezierPath bezierPathWithRect:selection];
[[NSColor blueColor] set];
[bp fill];
}
#end
The NSRect is calculated correctly, but when I call [self setNeedsDisplay], -drawRect is never called, and the rectangle is never drawn.
Is there any reason why -drawRect is never called on a PDFView subclass?
I have a similar use case. According to the docs, override PDFView's drawPage method instead. Continue to call setNeedsDisplay on the PDFView. It works, but it's a little slow. Working on overlaying a view right now instead.

Create an animation like that of an NSPopOver

I'm working at a custom Window object that is displayed as child in a parent Window.
For this object I'd like to create an animation like that of an NSPopover.
My first idea is to create a Screenshot of the child Window, than animate it using Core Animation and finally showing the real Window.
Before begging the implementation I would like to know if exists a better method and what you think about my solution.
It's not trivial. Here's how I do it:
#interface ZoomWindow : NSWindow
{
CGFloat animationTimeMultiplier;
}
#property (nonatomic, readwrite, assign) CGFloat animationTimeMultiplier;
#end
#implementation ZoomWindow
#synthesize animationTimeMultiplier;
- (NSTimeInterval)animationResizeTime: (NSRect)newWindowFrame
{
float multiplier = animationTimeMultiplier;
if (([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) != 0) {
multiplier *= 10;
}
return [super animationResizeTime: newWindowFrame] * multiplier;
}
#end
#implementation NSWindow (PecuniaAdditions)
- (ZoomWindow*)createZoomWindowWithRect: (NSRect)rect
{
// Code mostly from http://www.noodlesoft.com/blog/2007/06/30/animation-in-the-time-of-tiger-part-1/
// Copyright 2007 Noodlesoft, L.L.C.. All rights reserved.
// The code is provided under the MIT license.
// The code has been extended to support layer-backed views. However, only the top view is
// considered here. The code might not produce the desired output if only a subview has its layer
// set. So better set it on the top view (which should cover most cases).
NSImageView *imageView;
NSImage *image;
NSRect frame;
BOOL isOneShot;
frame = [self frame];
isOneShot = [self isOneShot];
if (isOneShot) {
[self setOneShot: NO];
}
BOOL hasLayer = [[self contentView] wantsLayer];
if ([self windowNumber] <= 0) // <= 0 if hidden
{
// We need to temporarily switch off the backing layer of the content view or we get
// context errors on the second or following runs of this code.
[[self contentView] setWantsLayer: NO];
// Force window device. Kinda crufty but I don't see a visible flash
// when doing this. May be a timing thing wrt the vertical refresh.
[self orderBack: self];
[self orderOut: self];
[[self contentView] setWantsLayer: hasLayer];
}
// Capture the window into an off-screen bitmap.
image = [[NSImage alloc] initWithSize: frame.size];
[[self contentView] lockFocus];
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect: NSMakeRect(0.0, 0.0, frame.size.width, frame.size.height)];
[[self contentView] unlockFocus];
[image addRepresentation: rep];
// If the content view is layer-backed the above initWithFocusedViewRect call won't get the content
// of the view (seems it doesn't work for CALayers). So we need a second call that captures the
// CALayer content and copies it over the captured image (compositing so the window frame and its content).
if (hasLayer)
{
NSRect contentFrame = [[self contentView] bounds];
int bitmapBytesPerRow = 4 * contentFrame.size.width;
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGContextRef context = CGBitmapContextCreate (NULL,
contentFrame.size.width,
contentFrame.size.height,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
[[[self contentView] layer] renderInContext: context];
CGImageRef img = CGBitmapContextCreateImage(context);
CFRelease(context);
NSImage *subImage = [[NSImage alloc] initWithCGImage: img size: contentFrame.size];
CFRelease(img);
[image lockFocus];
[subImage drawAtPoint: NSMakePoint(0, 0)
fromRect: NSMakeRect(0, 0, contentFrame.size.width, contentFrame.size.height)
operation: NSCompositeCopy
fraction: 1];
[image unlockFocus];
}
ZoomWindow *zoomWindow = [[ZoomWindow alloc] initWithContentRect: rect
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreBuffered
defer: NO];
zoomWindow.animationTimeMultiplier = 0.3;
[zoomWindow setBackgroundColor: [NSColor colorWithDeviceWhite: 0.0 alpha: 0.0]];
[zoomWindow setHasShadow: [self hasShadow]];
[zoomWindow setLevel: [self level]];
[zoomWindow setOpaque: NO];
[zoomWindow setReleasedWhenClosed: NO];
[zoomWindow useOptimizedDrawing: YES];
imageView = [[NSImageView alloc] initWithFrame: [zoomWindow contentRectForFrameRect: frame]];
[imageView setImage: image];
[imageView setImageFrameStyle: NSImageFrameNone];
[imageView setImageScaling: NSScaleToFit];
[imageView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[zoomWindow setContentView: imageView];
[self setOneShot: isOneShot];
return zoomWindow;
}
- (void)fadeIn
{
[self setAlphaValue: 0.f];
[self orderFront: nil];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration: 0.3];
[[self animator] setAlphaValue: 1.f];
[NSAnimationContext endGrouping];
}
- (void)zoomInWithOvershot: (NSRect)overshotFrame withFade: (BOOL)fade makeKey: (BOOL)makeKey
{
[self setAlphaValue: 0];
NSRect frame = [self frame];
ZoomWindow *zoomWindow = [self createZoomWindowWithRect: frame];
zoomWindow.alphaValue = 0;
[zoomWindow orderFront: self];
NSDictionary *windowResize = #{NSViewAnimationTargetKey: zoomWindow,
NSViewAnimationEndFrameKey: [NSValue valueWithRect: overshotFrame],
NSViewAnimationEffectKey: NSViewAnimationFadeInEffect};
NSArray *animations = #[windowResize];
NSViewAnimation *animation = [[NSViewAnimation alloc] initWithViewAnimations: animations];
[animation setAnimationBlockingMode: NSAnimationBlocking];
[animation setAnimationCurve: NSAnimationEaseIn];
[animation setDuration: 0.2];
[animation startAnimation];
zoomWindow.animationTimeMultiplier = 0.5;
[zoomWindow setFrame: frame display: YES animate: YES];
[self setAlphaValue: 1];
if (makeKey) {
[self makeKeyAndOrderFront: self];
} else {
[self orderFront: self];
}
[zoomWindow close];
}
This is implemented in an NSWindow category. So you can call:
- (void)zoomInWithOvershot: (NSRect)overshotFrame withFade: (BOOL)fade makeKey: (BOOL)makeKey
on any NSWindow.
I should add that I haven't been able to get both animations to run at the same time (fade and size), but the effect is quite similar to how NSPopover does it. Maybe someone else can fix the animation issue.
Needless to say this code works on 10.6 too where you don't have NSPopover (that's why I have written it in the first place).

Sliding a CCMenu

I have a Menu ("myMenu") containing CCMenuItemImages. I would like this menu to detect finger swipes and slide accordingly.
My problem is that the CCMenuItemImages seem to absorb the touch event. The swipe works fine when the user touches the menu outside of the CCMenuItemImages, but not when the touch happens on these.
I have tried to put my menu items in a layer to detect touches (refering to answer Scrollable menu using MenuItem's), but this doesn't seem to work either. Any idea why ?
+(id) scene
{
CCScene *scene = [CCScene node];
ModeMenuScene *layer = [ModeMenuScene node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if( (self=[super init] )) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *background = [CCSprite spriteWithFile:#"bg.png"];
background.position=ccp(winSize.width/2,winSize.height/2);
[self addChild:background];
mode1 = [CCMenuItemImage itemFromNormalImage:#"Mode1.png" selectedImage: #"Mode1.png" target:self selector:#selector(goToMode1:)];
mode1label = [CCLabelTTF labelWithString:[NSString stringWithFormat:#"Level 1 %d", n] dimensions:CGSizeMake(220,53) alignment:UITextAlignmentCenter fontName:#"Arial" fontSize:20.0];
mode1label.color = ccc3(167,0,0);
mode1label.position=ccp(55,-30);
[mode1 addChild:mode1label];
// here same kind of code to define mode2,mode3,mode4 (taken out to reduce size of code)
myMenu=[CCMenu menuWithItems:mode1,mode2,mode3,mode4,nil];
[myMenu alignItemsHorizontallyWithPadding:25];
myMenu.position=ccp(winSize.width/2+40,180);
menuLayer = [CCLayer node];
[menuLayer addChild:myMenu];
[self addChild:menuLayer];
[self enableTouch];
}
return self;
}
-(void) disableTouch{
self.isTouchEnabled=NO;
menuLayer.isTouchEnabled=NO;
}
-(void) enableTouch{
self.isTouchEnabled=YES;
menuLayer.isTouchEnabled=YES;
}
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
if(location.y>100 && location.y<260) {
draggingMenu=1;
x_initial = location.x;
}
else draggingMenu=0;
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
if(draggingMenu==1) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
int x = myMenu.position.x+location.x-x_initial;
x = MAX(0,x);
x = MIN(x,winSize.width/2+40);
myMenu.position=ccp(x,180);
x_initial=location.x;
}
}
- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
draggingMenu=0;
}
- (void)dealloc {
[super dealloc];
}
#end
Solved it by adding :
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:INT_MIN+1 swallowsTouches:NO];
}
the problem was that CCMenuItemImage swallows the touches and has a high priority set at -128. Thus the need to set priority at INT_MIN+1

move frame up when keyboard pops in Xcode

#import "LoginScreen.h"
#define kTabBarHeight 1
#define kKeyboardAnimationDuration 0.3
#implementation LoginScreen
#synthesize userName,password,loginButton,scrollView;
BOOL keyboardIsShown;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
//make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
// CGSize scrollContentSize = CGSizeMake(1024,700 );
// [scrollView setContentSize : scrollContentSize];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
NSValue* boundsValue = [userInfo objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [boundsValue CGRectValue].size;
// resize the scrollview
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height += (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
// The kKeyboardAnimationDuration I am using is 0.3
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
- (void)keyboardWillShow:(NSNotification *)n
{
// This is an ivar I'm using to ensure that we do not do the frame size adjustment on the UIScrollView if the keyboard is already shown. This can happen if the user, after fixing editing a UITextField, scrolls the resized UIScrollView to another UITextField and attempts to edit the next UITextField. If we were to resize the UIScrollView again, it would be disastrous. NOTE: The keyboard notification will fire even when the keyboard is already shown.
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
NSValue* boundsValue = [userInfo objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [boundsValue CGRectValue].size;
// resize the noteView
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
// The kKeyboardAnimationDuration I am using is 0.3
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- (IBAction) loginButton: (id) sender{
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end
Can anybody tell me whats wrong in code below. The original view doesn't move up even though i am subtracting the keyboards height to the frame heights.
The scrollView doesn't move up when keyboard pops in? Am I missing some code here.
Well, the problem is that you're not telling your code where your text field is to begin with, so it has no idea where it needs to scroll from. You probably thought that your self.scrollView.frame does it, but that only tells the code the size of your ScrollView, not that it needs to scroll or should scroll. Here's what I did to get mine to work.
Look at the connections for one of your text fields. Drag and drop from the "Did Begin Editing" and "Did End Editing" into your .h file to create IBAction function declarations. Xcode is going to put functions into the .m, but replace them with these:
//even though these functions don't reference the IBAction that we placed for the
"DidBeginEditing" sender for a text field, it will still call these functions.
We need to let the code know what text field we just touched so we can go through
the functions that reset the view size if the text field is under the keyboard.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
currentTextField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
currentTextField = nil;
}
That reminds me, you'll need to declare currentTextField as a UITextField * in the .m:
#interface ThirdView : UIViewController{
UITextField *currentTextField;
BOOL keyboardIsShown;
}
My viewDidLoad, keyBoardWasShown, etc are a bit different from yours, but I'll just put them all here so you can see how I got it to work:
//This is code you actually add to get the view to scroll.
You should first connect an outlet from the ScrollView to the .h file so these
functions become available.
- (void)viewDidLoad {
//standard screen size is 320 X 460
// ---set the viewable frame of the scroll view---
// scrollView.frame = CGRectMake(0, 0, 320, 460);
//---set the content size of the scroll view---
// [scrollView setContentSize:CGSizeMake(320, 615)];
//the status bar is 20 pixels tall
//the navigation bar is 44 pixels tall
//---set the viewable frame of the scroll view---
//Note: for some reason, the origin (0,44) doesn't take into account the status bar, but it works anyway. However, the height of the scroll view does take it into account. Wierd, but whatever. So you have to make y1 = 44, and y2 = 460-44-20.
scrollView.frame = CGRectMake(0, 44, 320, 416);
//---set the content size of the scroll view---
[scrollView setContentSize:CGSizeMake(320, 571)];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setPrincipal_Amt:nil];
[self setAPR:nil];
[self setYears:nil];
[self setScrollView:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
if(keyboardIsShown)
return;
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
Notice that we've got to add 64 pixels to the keyboard height because the CGRect has
no idea that you have the status bar shown and a navigation bar within your view, so
you have to manually add it in.
CGRect aRect = self.view.frame;
aRect.size.height -= (kbSize.height + 64);
if (!CGRectContainsPoint(aRect, currentTextField.frame.origin) )
{
CGPoint scrollPoint = CGPointMake(0.0, currentTextField.frame.origin.y-kbSize.height + 64);
[scrollView setContentOffset:scrollPoint animated:YES];
}
keyboardIsShown = YES;
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
keyboardIsShown = NO;
}
//
I hope that helps...even though you did post this a while ago :) It took me a while to get it to work too. Very frustrating.

Drawing UIImage into CurrentContext

In my application I've used a UIImagePickerController to take a photo, and after I took the photo, I can't draw it using UIImageView because I want to draw some lines on it with my finger.
To this end I have written in draw rect methods this code:
- (void)drawRect:(CGRect)rect {
[self.myimage drawInRect: rect];
//Disegno rettangolo del tag
CGContextRef myContext = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(myContext, 0.5, 0.5, 0.5, 1.0);
CGContextSetLineWidth(myContext, 3.0f);
CGContextAddPath(myContext, pathTouches);
CGContextStrokePath(myContext);
}
and in touchesMoved:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationInView = [touch locationInView:self];
// Draw a connected sequence of line segments
CGPoint addLines[] =
{
//....
//some lines
};
CGMutablePathRef newPath = CGPathCreateMutable();
CGPathRelease(pathTouches);
pathTouches = CGPathCreateMutableCopy(newPath);
CGPathRelease(newPath);
CGPathAddLines(pathTouches, NULL, addLines, sizeof(addLines)/sizeof(addLines[0]));
[self setNeedsDisplay];
}
Is it correct to call [self setNeedsDisplay]; every time I move my finger, or there is a better way to do this?
i have done this but stuck at another problem...here is your solution...
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
// Dismiss the image selection, hide the picker and
//show the image view with the picked image
[picker dismissModalViewControllerAnimated:YES];
imagePickerController.view.hidden = YES;
[imagePickerController release];
imageView.image = image;
imageView.hidden = NO;
[imageView setFrame:CGRectMake(0, 20, 320, 396)];
[window bringSubviewToFront:imageView];
}
then
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch view] == EditImageView)
{
lastPoint = currentPoint;
lastPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(EditImageView.frame.size);
[EditImageView.image drawInRect:CGRectMake(0, 0, EditImageView.frame.size.width, EditImageView.frame.size.height)];
//sets the style for the endpoints of lines drawn in a graphics context
ctx = UIGraphicsGetCurrentContext();
CGContextSetLineCap(ctx, kCGLineCapRound);
//sets the line width for a graphic context
CGContextSetLineWidth(ctx,10.0);
//set the line colour
CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);
//creates a new empty path in a graphics context
CGContextBeginPath(ctx);
CGContextSetAllowsAntialiasing(ctx,TRUE);
//begin a new path at the point you specify
CGContextMoveToPoint(ctx, currentPoint.x, currentPoint.y);
//Appends a straight line segment from the current point to the provided point
CGContextAddLineToPoint(ctx, lastPoint.x,lastPoint.y);
//paints a line along the current path
CGContextStrokePath(ctx);
EditImageView.image = UIGraphicsGetImageFromCurrentImageContext();
[EditImageView setNeedsDisplay];
CGContextSaveGState(ctx);
UIGraphicsEndImageContext();
currentPoint = lastPoint;
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == EditImageView)
{
currentPoint=[touch locationInView:self.view];
}
}
where currentPoint and lastPoint are CGPoint Declared in Header File.

Resources