Reputation: 616
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!
Upvotes: 3
Views: 5917
Reputation: 616
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!
Upvotes: 2
Reputation: 4071
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...
}
Upvotes: 1