Search code examples
ipadloadinguisplitviewcontroller

iOS (iPad): Show loading screen on top of UISplitView


In my application I am reveiving data from a server. With this data I fill a table view (MasterViewController) and when I select one of the items in this table it is displayed with detail information in the DetailViewController. These information is loaded on every startup of the application or when the user presses a refresh button.

While receiving data from the server I want do display a view that contains a UIActivityIndicatorView and a label that says "Loading...". This works just fine when my application is started or refreshed in portrait mode. But when I try the same in landscape mode the size of my view is incorrect.

Here is the code I am using to load my view:

+ (SpinnerView *)loadSpinnerViewIntoView:(UIView *)superView {

    SpinnerView *spinnerView = [[SpinnerView alloc] initWithFrame:superView.bounds];

    if (!spinnerView)
        return nil;

    UIImageView *background = [[UIImageView alloc] initWithImage:[spinnerView addBackground]];
    background.alpha = 0.7;
    [spinnerView addSubview:background];

    UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    indicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
    indicator.center = superView.center;
    [spinnerView addSubview:indicator];
    [indicator startAnimating];   

    CGSize maximumLabelSize = CGSizeMake(296, 9999);
    CGSize expectedLabelSize = [[NSString stringWithString:@"Loading..."] sizeWithFont:[UIFont boldSystemFontOfSize:25.0f] constrainedToSize:maximumLabelSize];

    UILabel *loadingLbl = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, expectedLabelSize.width, expectedLabelSize.height)];
    loadingLbl.text = @"Loading...";
    loadingLbl.font = [UIFont boldSystemFontOfSize:25.0f];
    loadingLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    loadingLbl.backgroundColor = [UIColor clearColor];
    loadingLbl.textColor = [UIColor whiteColor];
    loadingLbl.center = CGPointMake(superView.center.x, superView.center.y - indicator.frame.size.height - 25);
    [spinnerView addSubview:loadingLbl];   

    [superView addSubview:spinnerView];

    CATransition *animation = [CATransition animation];
    [animation setType:kCATransitionFade];
    [[superView layer] addAnimation:animation forKey:@"layerAnimation"];

    return spinnerView;
}

This is called from my MasterViewController when I start updating my data:

spinner = [SpinnerView loadSpinnerViewIntoView:self.splitViewController.view];

The SpinnerView gets the same bounds as the view in that it is loaded. I don't really understand why it doesn't display properly in landscape mode. I hope my issue is understandable and anyone can help me.

Thanks in advance


Solution

  • I finally did it by changing the SinnerView call to:

    + (SpinnerView *)loadSpinnerViewIntoView:(UIView *)superView withFrame:(CGRect)frame {
    
        SpinnerView *spinnerView = [[SpinnerView alloc] initWithFrame:frame];
    
        if (!spinnerView)
            return nil;
    
        .
        .
        .        
    
        return spinnerView;
    }
    

    and calling a function from my viewDidLoad method like this:

    [self performSelectorOnMainThread:@selector(checkLaunchOrientation:) withObject:nil waitUntilDone:NO];
    

    Here's the function:

    - (void)checkLaunchOrientation:(id)sender {
    
        UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    
        if (UIInterfaceOrientationIsLandscape(orientation))
            spinner = [SpinnerView loadSpinnerViewIntoView:self.splitViewController.view withFrame:CGRectMake(0.0, 0.0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width)];
        else
            spinner = [SpinnerView loadSpinnerViewIntoView:self.splitViewController.view withFrame:self.splitViewController.view.bounds];
    }
    

    It's kind of a workaround, but it works for me...