viewDidAppear for subviews
Asked Answered
C

2

3

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 viewDidAppearfor 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!

Cracker answered 29/3, 2011 at 9:38 Comment(0)
C
2

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!

Cracker answered 31/3, 2011 at 22:8 Comment(0)
V
1

You should either be able to simply start your loading directly after calling [parentView addSubview:loadingView] or in your loading view (assuming it is subclassed) override didMoveToSuperview like so:

- (void)didMoveToSuperview {
    // [self superview] has changed, start loading now...
}
Visit answered 29/3, 2011 at 9:50 Comment(5)
Doesn't work. didMoveToSuperview doesn't mean, that the subview did actually appear, but only that it has been added to a superview. If I start loading in didMoveToSuperview the subview still get's visible only after the loading of the data.Cracker
When you say "loading", what are you doing? Are you waiting on a network operation or performing some sort of calculation?Visit
I load data from a CoreData database.Cracker
actually it's not "loading". I copy data from an object to another.Cracker
This definitely sounds like something that should be done off the main thread. If that's not an option, you might want to try calling your doSomeWork method momentarily after you add your loading subview. Like so: [self performSelector:@selector(doSomeWork) withObject:nil afterDelay:1/10]Visit

© 2022 - 2024 — McMap. All rights reserved.