1

Why this code isn't being executed correctly. I have tried setNeedsDisplay and setNeedsLayout but this code doesn't appear to be executed. Even when it does execute, it executes when its not supposed to and it executes it wrong meaning it draws the line in the wrong place and with random length. - (void)drawNW {

NSLog(@"%f",x1);
NSLog(@"%f",y1);

CGContextSetStrokeColorWithColor(c, [UIColor blueColor].CGColor);
CGContextSetLineWidth(c, 10.0);
CGContextMoveToPoint(c, x1, y1);
CGContextAddLineToPoint(c, -(sqrtf(2)/2)*length + x1, ((sqrtf(2)/2)*length + y1));
CGContextStrokePath(c);

length = line.bounds.size.height;

}

Length, x1, and y1 are floats constantly changing at a interval of 0.1 seconds by a NSTimer:

 NWTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(startMoving) userInfo:nil repeats:YES];

the timer calls this code which calls drawNW:

x1 = x1-2.5;
y1 = y1-2.5;
length= length+5;
[self drawNW];
aparande
  • 62
  • 5

1 Answers1

0

Your code for drawing stuff (CGContext... etc.) needs to be inside your class' drawRect method. Your timer-driven code should then just change the values of x1, y1 and length and then call [self setNeedsDisplay]. This tells iOS that the view needs to be redrawn, so that drawRect is then called.

As far as drawing the lines where you want them, I can't really tell what you're trying to do with this code.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • I tried this and it works, but every time i call setNeedsDisplay, it deletes the line it just drew and replaces it with a line at the new point (x1, y1). Is there anyway to store this line in an array or something. If not, then thank you anyways – aparande Mar 24 '13 at 15:06
  • Create a bitmap that's the same size as your view when the app starts. As each timer event fires, change the values of x1 etc. and draw the new line onto this bitmap, then call [self setNeedsDisplay]. Inside your `drawRect` you just copy this bitmap to the screen. See [this answer](http://stackoverflow.com/a/1962986/14606) for code. – MusiGenesis Mar 24 '13 at 23:23
  • You could also store just the coordinates of each new line in a collection of some sort (as you suggest), and then redraw the entire (expanding) set during each `drawRect` call, but this is inefficient and likely to slow down after awhile. – MusiGenesis Mar 24 '13 at 23:25
  • IMPORTANT: make sure you wrap the code in your timer event and in `drawRect` that accesses your offscreen bitmap in `@synchronized(self.offscreenBitmap) {...}`, just to be on the safe side. – MusiGenesis Mar 24 '13 at 23:28
  • I used the code you provided, but I don't know what to fill in for the bytesPerLine,<#void *data#>,<#size_t width#>, <#size_t bitsPerComponent#>, <#size_t bytesPerRow#>, <#CGColorSpaceRef space#> and <#CGBitmapInfo bitmapInfo#> if I want to make the bitMap the same size as my view. – aparande Mar 25 '13 at 14:06
  • bytesPerLine should probably be your view's width multiplied by four (since there are usually 4 bytes per pixel). It should be easy to experiment and come up with the correct figure for this. – MusiGenesis Mar 25 '13 at 14:28
  • I have filled out all the information except <#CGBitmapInfo bitmapInfo#>. I tried to pass it as nil, but its giving me an error. Do you have any idea what I fill this parameter as. – aparande Mar 29 '13 at 15:01
  • @Codeuser1.7: `kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big` – MusiGenesis Mar 29 '13 at 15:40
  • Now there is an exception: : CGBitmapContextCreateImage: invalid context 0x0 This is the code for my CGBitmapContextCreateImage: CGContextRef offscreen = CGBitmapContextCreate(bitmapData, self.bounds.size.width, self.bounds.size.height, self.bounds.size.height*4, (self.bounds.size.width)*4, colorRef,kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); – aparande Mar 31 '13 at 17:31
  • I don't think you want to multiply the *height* by 4 - just the width. – MusiGenesis Mar 31 '13 at 23:43