views:

47

answers:

2

Hi,

I am adding UIViews to a superview in the following loop:

int xValue = 0 ;
int yValue = 10;
for (NSString *element in characters) {
    UIView *newCharView = [[MyChar alloc] initWithFrame:CGRectMake(xValue,yValue,100,100)];
    [(MyChar *)newCharView initLayers:element];
    [[self view] addSubview:newCharView];
    [newCharView autorelease];

    if (xValue <= 240) {
        xValue+=22;
    } else {
        xValue = 0;
        yValue += 22;
    }

}

MYChar contains a method which fires an animation. I want the method to be called sequentially in my loop with a delay of, say, 0.2 seconds. How can I achieve this? I tried delaying the animation itself but obviously just get the same delay in all the UIViews.

A: 

Give this a try:

[self performSelector:@selector(postAnimationMethod) withObject:self afterDelay:0.2];
Winder
+2  A: 

You could try using something like this:

int xValue = 0 ;
int yValue = 10;
double delay = 0.2;
for (NSString *element in characters) {
    UIView *newCharView = [[MyChar alloc] initWithFrame:CGRectMake(xValue,yValue,100,100)];
    [self performSelector:@selector(delayedInitView:) withObject:element afterDelay:delay];

    if (xValue <= 240) {
        xValue+=22;
    } else {
        xValue = 0;
        yValue += 22;
    }
    delay += 0.2;

}

-(void) delayedInitView: (id) element {
    [(MyChar *) newCharView initLayers: element];
    [[self view] addSubview: newCharView];
    [newCharView autorelease];
}

You will have to experiment with that, as I don't know what exactly you are trying to achieve.

EDIT: Ouch, it's definitely not a good way to go with such a large amount of views. You could try using one background loop to init all of them. I would definitely have to think it over a lil more if I personally faced that problem, but here's a simple suggestion, you will have to tune it to your needs and probably take care of its thread/memory management safety:

[self performSelectorInBackground:@(backgroundInitViews:) withObject:characters]

-(void) backgroundInitViews: (NSArray*) elements {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    int xValue = 0 ;
    int yValue = 10;
    for (NSString *element in elements) {
        UIView *newCharView = [[MyChar alloc] initWithFrame:CGRectMake(xValue,yValue,100,100)];
        [(MyChar *) newCharView initLayers: element];
        [[self view] addSubview: newCharView];
        [newCharView autorelease];


        if (xValue <= 240) {
            xValue+=22;
        } else {
            xValue = 0;
            yValue += 22;
        }
        [NSThread sleepForTimeInterval:0.2];
    }
    [pool drain];
}
Estarriol
Thanks this works. Performance is fine in the simulator but on the Device (iPhone4) its terrible. I'm not saying its the code you've suggested but if I'm adding 140 UIViews, each containing up to 30 layers, is there a more performant way to do this?
codecowboy
I've just edited my response, this should increase performance a lot.
Estarriol