为什么我不能画画呢? (在iPhone中使用UIView) [英] Why I can't draw in a loop? (Using UIView in iPhone)

查看:151
本文介绍了为什么我不能画画呢? (在iPhone中使用UIView)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以用这个来画很多东西:

I can draw many things using this :

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方法中.然后,我想做类似的事情,但是这次,我的execute方法只能这样做:

So, it works, so, I put it into a command object's execute method. Then, I want to do similar thing, but this time, my execute method only do this:

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对象的方法.

This time, this is also a Command, and it is the execute method. But I take the for loop away. I will have another method that pass the inComingX , and inComingY into my Command object.

我的Drawing方法只是执行在我的drawingEngine中传递的Cmd:

My Drawing method is simply execute the Cmd that passed in my drawingEngine:

-(void)drawInContext:(CGContextRef)context
{
    [self.cmdToBeExecuted execute];
}

我还有分配方法来分配命令,

I also have the assign method to assign the command,:

-(void)assignCmd:(Command* )cmd{
    self.cmdToBeExecuted = cmd;

}

这就是我所谓的drawingEngine

And this is the way I called the drawingEngine

for(int k=0; k<5; k++){
    [self.drawingEngine assignCmd:[DrawingCmd setDrawingInformation:(10*k):0:@"dummy.png"]];
    [self.drawingEngine setNeedsDisplay];
}

它可以绘制,但可悲的是它只能绘制最后一个.为什么?以及如何解决?我可以在First代码中绘制所有内容,但是在我将循环带到外面并在最后一个代码中使用该循环之后,它仅绘制了最后一个.请帮助

It can draw, but the sad thing is it only draw the last one. Why? and how to fix it? I can draw all the things in my First code, but after I take the loop outside, and use the loop in last code, it just only draw the last one. Plz help

推荐答案

这是因为setNeedsDisplay实际上没有调用drawRect:.它只是将视图计划为在下一个方便的"时间(可能在下一次,应用程序重新进入运行循环)时重绘视图.由于在每次调用赋值函数时都覆盖了记住的命令对象,因此实际上drawRect:会被调用,因此只有最后分配的命令可用并且将被绘制.

That's because setNeedsDisplay does not actually call drawRect:. It simply schedules the view to be redrawn at the next "convenient" time, which is likely the next time, the application re-enters the run-loop. Since you overwrite the remembered command object on each call to the assignment function, by the time, the drawRect: is actually called, only the last assigned command is available and will be drawn.

一种更好的方法是:记住所有要绘制的命令,而不是最后一个命令,例如在数组中说:

A better way to do it would be: remember all commands to be drawn instead just the last one, say in an array, like:

@interface MyCanvas {
    ...
    NSMutableArray* commandList;
    ...
}

并将命令添加到该数组中,而不是分配单个命令成员:

and add commands to that array instead of assigning a single command member:

-(void) addCommand:(Command*) cmd {
    [self.commandList addObject: cmd];
}

然后应在您的draw方法中处理命令

The commands should then be processed in your draw method

for( Command* cmd in self.commandList ) {

    [cmd execute ...];
}

或者,您可以定义复杂"命令,该命令包含多个绘制步骤.

Alternatively, you could define "complex" commands, which consist of more than a single drawing step.

(编辑回答评论中的问题):您的原始代码确实起作用了,因为它可以在适当的单次调用中一​​次完成所有工作draw方法.您的最后一个代码在运行时根本不会绘制任何内容.它只是简单地记住(通过命令对象)必须要做的事情,并通知视图,它应该在下一次方便的情况下重新绘制自身 .重要的是要注意,setNeedsDisplay不会不会直接进行任何重新绘制.它只是将视图标记为脏",稍后将在Cocoa运行时中由其他代码拾取.

(EDIT to answer the question in the comments): Your original code did work, because it does the work all in one place in a single invocation of the appropriate draw method. Your last code does not draw anything at all while it runs. It simply remembers (via command object) that something has to be done, and notifies the view, that it should redraw itself on the next convenient occasion. It is important to note, that setNeedsDisplay will not cause any repainting to be done directly. It simply marks the view as "dirty", which will be picked up by other code in the Cocoa run-time later.

您的代码中还有另一件事,我觉得有点可疑:您的方法drawInContext:带有上下文参数,该参数被忽略.它既不传递给命令对象的execute方法,也不作为实例变量中的某种当前"图形上下文安装.如果您希望drawRect:(或命令的execute方法)中的代码实际使用该上下文,则必须将其传递给应该使用它的任何人.

There is another thing in your code which I find slightly suspicious: your method drawInContext: takes a context argument, which is simply ignored. Neither is it passed on to the execute method of you command object, nor is it installed as some kind of "current" drawing context in an instance variable or somesuch. If you expect the code in drawRect: (or the command's execute method) to actually use that context, you have to pass it on to whoever is supposed to use it.

这篇关于为什么我不能画画呢? (在iPhone中使用UIView)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆