Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone - Splash Screen with progress bar

I tried to create a SplashView which display the Default.png in the background and a UIProgressBar in front. But the splash screen is not being updated...

Inside my view controller I load first the splash view with a parameter how many steps my initialisation has and then I start a second thread via NSTimer and after each initialisation step I tell the SplashView to display the new progress value.

All looks good in theory, but when running this app the progress bar is not being updated (the method of the splash screen receives the values, I can see it in the logs). I also tried to add usleep(10000); in between to give the view updates a bit time and also instead of using the progress bar I drew directly on the view and called [self setNeedsDisplay]; but all didn't work :/

What am I doing wrong?

Thanks for your help!

Tom

Here is some code:

SPLASHSCREEN:
- (id)initWithFrame:(CGRect)frame withStepCount:(int)stepCount {
    if (self = [super initWithFrame:frame]) {
        // Initialization code

        background = [[UIImageView alloc] initWithFrame: [self bounds]];
        [background setImage: [UIImage imageWithContentsOfFile: [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"Default.png"]]];
        [self addSubview: background];

        progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
        [progressView setFrame:CGRectMake(60.0f, 222.0f, 200.0f, 20.0f)];
        [progressView setProgress: 0.0f];

        stepValue = 1.0f / (float)stepCount;

        [self addSubview:progressView];
    }
    return self;
}

- (void)tick {
    value += stepValue;
    [progressView setProgress: value];
}



VIEWCONTROLLER:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {

        splashView = [[SplashView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 320.0f, 480.0f) withStepCount:9];
        [self setView: splashView];

        NSTimer* delayTimer;
        delayTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(finishInitialization) userInfo:nil repeats:NO];
    }
    return self;
}

- (void)finishInitialization {
    // do some stuff, like allocation, opening a db, creating views, heavy stuff...
    [splashView tick]; // this should update the progress bar...

    // do some stuff, like allocation, opening a db, creating views, heavy stuff...
    [splashView tick]; // this should update the progress bar...

    // init done... set the right view and release the SplashView
}
like image 340
crashtesttommy Avatar asked Feb 06 '26 00:02

crashtesttommy


2 Answers

As mentioned in another answer, for some finite amount of time, as your app is being launched, Default.png is displayed and you have no control over it. However, if in your AppDelegate, you create a new view that displays the same Default.png, you can create a seamless transition from the original Default.png to a view that you can add a progress bar to.

Now, presumably, you have created a view or similar and you are updating a progress bar every so often in order to give the user some feedback. The challenge here is that your view is only drawn when it gets called to do a drawRect. If, however, you go from AppDelegate to some initialization code to a viewcontroller's viewDidLoad, without the run loop getting a chance to figure out which views need to have drawRect called on, then your view will never display its status bar.

Therefore in order to accomplish what you want, you have to either make sure that drawRect gets called, such as by pushing off a lot of your initialization code into other threads or timer tasks, or you can force the drawing by calling drawRect yourself, after setting up contexts and such.

If you go with the background tasks, then make sure your initialization code is thread-safe.

like image 175
mahboudz Avatar answered Feb 08 '26 00:02

mahboudz


Default.png is just a graphic, a static image shown while the application is launching. If you want to show further progress, you'll have to show everything at the applicationDidLaunch phase. Show your modal "Splash Screen" there first (Create a view controller, add its view as a subview of your main window) and dismiss it when you are done whatever additional loading you needed to do.

like image 39
jbrennan Avatar answered Feb 08 '26 01:02

jbrennan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!