There are a number of apps in the App Store that launch with a set of closed doors, these are then opened to present the actual UI underneath it.

I had to create this effect for an app I wrote for a client http://itunes.com/apps/jkmuaythai

I’d assumed when I started that this would be a relatively simple task, just take the initial default image, cut it in half and a simple bit of animation would move them out of the way. What I hadn’t counted on is getting the orientation of the device from launch is not straightforward. The trick is to remember that the first view that is loaded will always assume it’s in Portrait mode, the view is then informed via the willRotate method that in fact the orientation is different and you can then handle this appropriately. The second trick is knowing that the willRotate takes a little bit of time to fire, so it’s now a simple case of delaying the call to the method that handles the animation.

The viewWillAppear method loads the images assuming that the view is in portrait and sets up a timer to call the openDoors method


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-(void)viewWillAppear:(BOOL)animated {
    //All apps start in portrait mode, with the home button at the bottom,
    //If the device is being held with the home button in any other location then a
    //willRotate is fired!
    isPortrait = YES;
    doorsClosed = YES;

    //We assume we are in portrait mode until told otherwise
    self.leftDoor.image = [UIImage imageNamed:@"DoorLeftiPadPortrait.png"];
    self.rightDoor.image = [UIImage imageNamed:@"DoorRightiPadPortrait.png"];
    self.backgroundSplash.image = [UIImage imageNamed:@"SlideBackgroundiPadPortrait.png"];

    //Add a delay to the open doors sequence, this allows the OS to determine
    //the correct orientaion and fire the all important willRotate

    [NSTimer scheduledTimerWithTimeInterval: 3.5
                                     target: self
                                   selector: @selector(openDoors)
                                   userInfo: nil
                                    repeats: NO];
}

The willRotate method then ensures that the correct image is loaded


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    isPortrait = UIDeviceOrientationIsPortrait(toInterfaceOrientation);
    if (!isPortrait) {
        //If the doors haven't already been opened then change them to the landscape ones
        if (doorsClosed) {
            self.leftDoor.image = [UIImage imageNamed:@"DoorLeftiPadLandscape.png"];
            self.rightDoor.image = [UIImage imageNamed:@"DoorRightiPadLandscape.png"];
        }
        self.backgroundSplash.image = [UIImage imageNamed:@"SlideBackgroundiPadLandscape.png"];
    } else {
        self.backgroundSplash.image = [UIImage imageNamed:@"SlideBackgroundiPadPortrait.png"];
    }
}

The openDoors method then just works out how far to move the images and kicks of the animation, I’ve included the old UIView beginAnimation and the Blocks way


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-(void)openDoors {
    //Determine how far the doors need to move for them to disappear from view
    float adjust = (CGRectGetWidth(self.view.frame) > CGRectGetHeight(self.view.frame)) ? CGRectGetWidth(self.view.frame) : CGRectGetHeight(self.view.frame);
    //Retrieve the original frame and then adjust the X position accordingly
    CGRect leftFrame = self.leftDoor.frame;
    CGRect rightFrame = self.rightDoor.frame;;

    leftFrame.origin.x = -adjust;
    rightFrame.origin.x += adjust;

//Old School Animation

//Set up the animation, change the frames and commit it
//  [UIView beginAnimations:@"swipe" context:nil];
//  [UIView setAnimationDuration:1.2];
//  [UIView setAnimationDelay:0.0];
//  [UIView setAnimationDelegate:self];
//
//      self.leftDoor.frame = leftFrame;
//  self.rightDoor.frame = rightFrame;
//
//  [UIView commitAnimations];

//Blocks
    [UIView animateWithDuration:1.2
                     animations:^{
                        self.leftDoor.frame = leftFrame;
                        self.rightDoor.frame = rightFrame;
                     }
    ];

    doorsClosed = NO;
}

Note this effect only works if the app is launching for the first time, i.e. not from the background.

I’ve put together a sample project that puts this all into practice

https://github.com/Flexicoder/OpenDoorsDemo

Hope you find this useful, or if you have a better way of creating the same effect please let me know

Problems?

We have a new Questions and Answers section so you can get help from the awesome community.

Ask a Question

Enjoyed this post?

Subscribe to our RSS Feed or Follow us on twitter to keep up to date with the latest from iOS-Blog. Remember, Sharing is caring so please click one of the following options:

Tags: , ,