注册 | 登录

objective c - How to use drawRect to draw in a existing view?

itPublisher 分享于



up vote 2 down vote favorite 1 I'm doing a GPS tracking app. Every time it receives a Latitude/Longitude it converts it to (x,y) coordinates and calls drawRect to draw a line between two (x,y) pairs. However, the drawRect method just clear all the old contents before it draw new thing. How I can make the drawRect to draw new thing on the existing canvas? Thanks in advance here is my viewController.h #import <UIKit/UIKit.h>

#import <CoreLocation/CoreLocation.h>

@class routetrack;

@interface simpleDrawViewController : UIViewController <CLLocationManagerDelegate> {

CLLocationManager *locationManager;

IBOutlet routetrack *routeroute;

float latOld;

float longOld;

float latNew;

float longNew;


- (IBAction) gpsValueChanged;

@property (nonatomic,retain) CLLocationManager


@property (retain,nonatomic) routetrack *routeroute;

ViewController.m #import "simpleDrawViewController.h"

#import "routetrack.h"

@implementation simpleDrawViewController

@synthesize locationManager,btn,routeroute;

- (IBAction) gpsValueChanged{

[routeroute setLocationX:longNew setLocationY:latNew

oldLocation:longOld oldLocationY:latOld ];

[routeroute setNeedsDisplay];


- (void)viewDidLoad {

[super viewDidLoad];

if (nil == locationManager)

locationManager = [[CLLocationManager alloc] init];

locationManager.delegate = self;

locationManager.desiredAccuracy = kCLLocationAccuracyBest;

[locationManager startUpdatingLocation];


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


- (void) locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation

fromLocation:(CLLocation *)oldLocation


if (oldLocation) {






else {






[self gpsValueChanged];


- (void) locationManager:(CLLocationManager *)manager didFailwithError:

(NSError *)error


if([error code] == kCLErrorDenied)

[locationManager stopUpdatingLocation];

NSLog(@"location manger failed");


- (void)dealloc {

[locationManager release];

[super dealloc];



my drawing class, a subclass of UIView #import "routetrack.h"

@implementation routetrack

- (void) setLocationX:(float) loX setLocationY:(float) loY

oldLocation:(float) oldX oldLocationY:(float) oldY {

self->locationX = loX;

self->locationY = loY;

self->oldLoX = oldX;

self->oldLoY = oldY;

scaleX= 36365.484375;

scaleY= 99988.593750;

maxLat= 53.3834;

maxLog= -6.5976;

drawX = locationX;

drawY = locationY;

tempX=(maxLog - drawX) * scaleX;


- drawY) * scaleY;

lastX = (int) tempX;

lastY = (int) tempY;

drawX = oldLoX;

drawY = oldLoY;

tempX=(maxLog - drawX) * scaleX;


- drawY) * scaleY;

startX = (int) tempX;

startY = (int) tempY;


- (id)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {


return self;


- (void)drawRect:(CGRect)rect {

int firstPointX = self->startX;

int firstPointY = self->startY;

int lastPointX = self->lastX;

int lastPointY = self->lastY;

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

CGContextSetLineWidth(context, 2.0);

CGContextMoveToPoint(context, firstPointX, firstPointY);

CGContextAddLineToPoint(context, lastPointX , lastPointY);



objective-c ios drawing draw drawrect
  this question edited Feb 24 '12 at 19:17 yuji 15.1k 4 46 57 asked Jul 17 '11 at 15:24 Kin 11 3      Never use the arrow notation self->locationX unless you really know what you're doing (this is almost never correct). This should be self.locationX and you should include @synthesize locationX; to create the accessors. –  Rob Napier Jul 18 '11 at 13:38

 |  2 Answers

up vote 4 down vote UIView does not have a canvas model. If you want to keep a canvas, you should create a CGLayer or a CGBitmapContext and draw onto that. Then draw that in your view. I would create an ivar for a CGLayerRef, and then drawRect: would look something like this (untested): - (void)drawRect:(CGRect)rect {

if (self.cgLayer == NULL) {

CGLayerRef layer = CGLayerCreateWithContext(UIGraphicsContextGetCurrent(), self.bounds, NULL);

self.cgLayer = layer;



... various Core Graphics calls with self.cgLayer as the context ...

CGContextDrawLayerInRect(UIGraphicsContextGetCurrent(), self.bounds, self.cgLayer);


Whenever you wanted to clear your canvas, just self.cgLayer = NULL. setCgLayer: would be something like this: - (void)setCgLayer:(CGLayerRef)aLayer {



cgLayer_ = aLayer;


  this answer answered Jul 17 '11 at 16:48 Rob Napier 164k 22 235 352      @Kin, make sure to post comments as comments, not answers. The moderator has removed your non-answer answer. The CGLayerRef would be an instance variable (ivar) on the view. It should have a name like RouteTrackView, not "routetrack". –  Rob Napier Jul 18 '11 at 13:35

 |  up vote 1 down vote What exactly to you mean by "old contents"? If you want to draw a line from your GPS data, you have to draw all points every time in the implementation of drawRect.
  this answer edited Jul 17 '11 at 16:24 answered Jul 17 '11 at 16:14 tomk 1,142 1 8 13      eg. first time GPS got lat/long and the function use that data to draw a line and display it. But next time GPS got new data, the old line is disappear and a new line is drawn. That's not I want. I want to the old line exist and draw a new line. –  Kin Jul 17 '11 at 16:27      Exactly. You have do draw all lines, every time. So you need to store all your coordinates in an NSMutableArray for example and draw the contents of the whole array im drawRect. –  tomk Jul 17 '11 at 16:44


up vote 2 down vote favorite 1 I'm doing a GPS tracking app. Every time it receives a Latitude/Longitude it converts it to (x,y) coordinates and calls drawRect to draw a line betwe








您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱