【问题标题】:How to use drawRect to draw in a existing view?如何使用 drawRect 在现有视图中绘制?
【发布时间】:2011-07-17 15:24:52
【问题描述】:

我正在做一个 GPS 跟踪应用程序。每次接收到纬度/经度时,它都会将其转换为 (x,y) 坐标并调用 drawRect 在两个 (x,y) 对之间绘制一条线。

然而,drawRect 方法只是在绘制新内容之前清除所有旧内容。如何使 drawRect 在现有画布上绘制新事物?提前致谢

这是我的 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

我的绘图类,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);

}

【问题讨论】:

  • 永远不要使用箭头符号self-&gt;locationX,除非你真的知道你在做什么(这几乎是不正确的)。这应该是 self.locationX 并且您应该包括 @synthesize locationX; 来创建访问器。

标签: objective-c ios drawing draw drawrect


【解决方案1】:

UIView 没有画布模型。如果你想保留一个画布,你应该创建一个CGLayerCGBitmapContext 并在上面绘制。然后在你的视图中绘制它。

我会为 CGLayerRef 创建一个 ivar,然后 drawRect: 看起来像这样(未经测试):

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

只要您想清除画布,只需self.cgLayer = NULL

setCgLayer: 会是这样的:

- (void)setCgLayer:(CGLayerRef)aLayer {
    CGLayerRetain(aLayer);
    CGLayerRelease(cgLayer_);
    cgLayer_ = aLayer;
}

【讨论】:

  • @Kin,确保将 cmets 发布为 cmets,而不是答案。版主已删除您未回答的答案。 CGLayerRef 将是视图上的实例变量 (ivar)。它应该有一个类似 RouteTrackView 的名称,而不是“routetrack”。
【解决方案2】:

“旧内容”对您来说究竟是什么意思?如果你想从你的 GPS 数据中画一条线,你必须在 drawRect 的实现中每次都画出所有的点。

【讨论】:

  • 例如。 GPS第一次获得纬度/经度,该功能使用该数据绘制一条线并显示它。但下次 GPS 获取新数据时,旧线消失并绘制新线。那不是我想要的。我想旧线存在并画一条新线。
  • 没错。你必须画出所有的线,每次。因此,例如,您需要将所有坐标存储在 NSMutableArray 中并绘制整个数组 im drawRect 的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多