Jochen Jochen - 3 months ago 7
Objective-C Question

viewDidAppear for subviews

I want to load some data when a button is pressed and show a "loading view" as a subview of my current view while it's loading.

So I want to start loading only after the subview did appear. If not my UI gets stuck without a notice (and the subview only shows after the loading is done).

Is there a way to use something like

viewDidAppear
for subviews?

Doing the work right after the
addSubview:
like this doesn't work:

- (void)doSomeWorkAndShowLoadingView
{
UIView *loadingView = [[[UIView alloc] initWithFrame:self.view.frame] autorelease];
loadingView.backgroundColor = [UIColor redColor];
[self.view addSubview:loadingView];
[self doSomeWork];
[loadingView removeFromSuperview];
}
- (void)doSomeWork
{
sleep(5);
}


(I don't want to do the loading on a new thread, because is's CoreData i'm working on, which is't thread safe).

Thank You!

Answer

I found a solution:

Adding the subview with an animation I could use - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag to call something like subviewDidAppear of the delegate of the subview.

In subclass of UIView:

#define KEY_SHOW_VIEW @"_ShowLoadingView_"
#define KEY_HIDE_VIEW @"_HideLoadingView_"
- (void)addToSuperview:(UIView *)theSuperview
{

    [theSuperview addSubview:self];   

    CATransition *animation = [CATransition animation];
    [animation setDuration:0.2];
    [animation setType:kCATransitionFade];
    [animation setDelegate:self];
    [animation setRemovedOnCompletion:NO];
    [animation setValue:KEY_SHOW_VIEW forKey:@"animation_key"];
    [[theSuperview layer] addAnimation:animation forKey:nil];

}

- (void)removeFromSuperview
{
    CATransition *animation = [CATransition animation];
    [animation setDuration:0.2];
    [animation setType:kCATransitionFade];
    [animation setDelegate:self];
    [animation setRemovedOnCompletion:NO];
    [animation setValue:KEY_HIDE_VIEW forKey:@"animation_key"];
    [[self.superview layer] addAnimation:animation forKey:nil]; 

    [super removeFromSuperview];
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{    
    NSString* key = [anim valueForKey:@"animation_key"];
    if ([key isEqualToString:KEY_SHOW_VIEW]) {
        if (self.delegate) {
            if ([self.delegate respondsToSelector:@selector(loadingViewDidAppear:)]) {
                [self.delegate loadingViewDidAppear:self];
            } 
        }
    } else if ([key isEqualToString:KEY_HIDE_VIEW]){
        [self removeFromSuperview];
    }
}

This got me the results I was looking for.

Thanks again for your help!