How to use drawRect to draw in a existing view?

自古美人都是妖i 提交于 2019-12-30 11:26:27

问题


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  *locationManager;
@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) {

            latOld=oldLocation.coordinate.latitude;
            longOld=oldLocation.coordinate.longitude;
            latNew=newLocation.coordinate.latitude;
            longNew=newLocation.coordinate.longitude;   
}

        else {
            latOld=53.3834;
            longOld=-6.5876;
            latNew=53.3835;
            longNew=-6.5877;
        }

        [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];
}

@end

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;
    tempY=(maxLat   - drawY) * scaleY;

    lastX = (int) tempX;
    lastY = (int) tempY;

    drawX = oldLoX;
    drawY = oldLoY;

    tempX=(maxLog - drawX) * scaleX;
    tempY=(maxLat   - 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);

    CGContextStrokePath(context);

}

回答1:


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;
        CGLayerRelease(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 {
    CGLayerRetain(aLayer);
    CGLayerRelease(cgLayer_);
    cgLayer_ = aLayer;
}



回答2:


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.



来源:https://stackoverflow.com/questions/6724800/how-to-use-drawrect-to-draw-in-a-existing-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!