我可以用这个来画很多东西:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"dummy2.png" ofType:nil];
UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
image = CGImageRetain(img.CGImage);
CGRect imageRect;
double x = 0;
double y = 0;
for (int k=0; k<someValue; k++) {
x += k;
y += k;
imageRect.origin = CGPointMake(x, y);
imageRect.size = CGSizeMake(25, 25);
CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, image);
}
}
CGImageRelease(img.CGImage);
所以,它有效,所以,我将它放入命令对象的execute方法中。然后,我想做类似的事情,但这一次,我的执行方法只做这个:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"dummy2.png" ofType:nil];
UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
image = CGImageRetain(img.CGImage);
CGRect imageRect;
double x = inComingX;
double y = inComingY;
imageRect.origin = CGPointMake(x, y);
imageRect.size = CGSizeMake(25, 25);
CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, image);
CGImageRelease(img.CGImage);
这次,这也是一个Command,它是execute方法。但我接受了for循环。我将有另一种方法将inComingX和inComingY传递给我的Command对象。
我的绘图方法只是执行我在drawingEngine中传递的Cmd:
-(void)drawInContext:(CGContextRef)context
{
[self.cmdToBeExecuted execute];
}
我还有assign方法来分配命令:
-(void)assignCmd:(Command* )cmd{
self.cmdToBeExecuted = cmd;
}
这就是我调用drawingEngine的方式
for(int k=0; k<5; k++){
[self.drawingEngine assignCmd:[DrawingCmd setDrawingInformation:(10*k):0:@"dummy.png"]];
[self.drawingEngine setNeedsDisplay];
}
它可以画画,但可悲的是它只画了最后一个。为什么?以及如何解决它?我可以在我的第一个代码中绘制所有内容,但是在我将循环放在外面并在最后一个代码中使用循环之后,它只绘制最后一个代码。 Plz帮助
答案 0 :(得分:4)
那是因为setNeedsDisplay
实际上并未调用drawRect:
。它只是在下一个“方便”时间安排视图重绘,这可能是下一次,应用程序重新进入运行循环。由于在每次调用赋值函数时都会覆盖记住的命令对象,到时候实际调用drawRect:
,只有最后分配的命令可用并且将被绘制。
更好的方法是:记住要绘制的所有命令,而不是最后一个,比如在数组中,例如:
@interface MyCanvas {
...
NSMutableArray* commandList;
...
}
并向该数组添加命令,而不是分配单个命令成员:
-(void) addCommand:(Command*) cmd {
[self.commandList addObject: cmd];
}
然后应在draw
方法
for( Command* cmd in self.commandList ) {
[cmd execute ...];
}
或者,您可以定义“复杂”命令,其中包含多个绘图步骤。
(编辑以回答评论中的问题):您的原始代码确实有效,因为它可以在适当的单一调用中的所有位置完成工作draw
方法。您的上一个代码在运行时根本不会绘制任何内容。它只记得(通过命令对象)必须要做的事情,并通知视图,它应该在下一个方便的场合重新绘制 。重要的是要注意,setNeedsDisplay
将不导致任何重新绘制直接完成。它只是将视图标记为“脏”,稍后将在Cocoa运行时被其他代码拾取。
您的代码中还有另一件事我觉得有点可疑:您的方法drawInContext:
采用了一个上下文参数,它被简单地忽略了。它既不会传递给命令对象的execute
方法,也不会在实例变量中安装为某种“当前”绘图上下文或某些东西。如果您希望drawRect:
(或命令的execute
方法)中的代码实际使用该上下文,则必须将其传递给应该使用它的任何人。