Restricting Orientations in different view controllers

At some point you may want to restrict certain device orientations to certain view controllers. Its quite easy to do from your App Delegate.

First add a new variable to your AppDelegate.swift file:

   var allowableOrientations: UIInterfaceOrientationMask = .All

Next, implement the application:supportedInterfaceOrientationsForWindow function in the same file:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    return allowableOrientations;
}

This will be called whenever you rotate the device to determine if that orientation is allowed. It doesn’t, however, force a rotation. We can implement another function in the same file to handle setting the allowableOrientations file and making sure the current orientation is one of those:

    func setAllowableOrientations(orientationMask:UIInterfaceOrientationMask,
                               defaultOrientation:UIInterfaceOrientation) {
        self.allowableOrientations=orientationMask;
        if ((orientationMask.rawValue & UInt(UIDevice.currentDevice().orientation.rawValue)) == 0) {
            UIDevice.currentDevice().setValue(defaultOrientation.rawValue, forKey: "orientation")
        }
    }

To use it, simply call this function from your View Controller’s viewDidLoad function, similar to this:

    (UIApplication.sharedApplication().delegate as! AppDelegate).setAllowableOrientations(.Landscape,defaultOrientation: .LandscapeRight)

That’s it!

ERROR iTMS-90022: Missing required icon file. (120×120)

If you get a iTMS-90022 error message and you have what looks like the proper 120×120 icon file in your Images.xcassets, you can try to get this working the old fashioned way by adding the appropriate .png files to your project and updating your Info*.plist file. The entries for the plist file for iPhone targets should be:

<key>CFBundleIconFiles</key>
<array>
    <string>Icon-Small</string>
    <string>Icon-Small-40</string>
    <string>Icon-Small-50</string>
    <string>Icon</string>
    <string>Icon-60</string>
    <string>Icon-72</string>
</array>

Make sure your png files (along with the @2, @3 versions) match this naming convention as well. For me, it was the ‘Spotlight’ files that were misnamed to ‘Icon-40.png’, etc instead of ‘Icon-Small-40.png’.

The entries for the plist file for iPad targets should be:

<key>CFBundleIconFiles~ipad</key>
<array>
    <string>Icon-Small</string>
    <string>Icon-Small-40</string>
    <string>Icon-Small-50</string>
    <string>Icon-72</string>
    <string>Icon-76</string>
</array>

If you have a universal app, add both to your plist file, and make sure the matching png files are all in your project as well.

More info here if you are a developer.

Fixing the status bar visible after photo roll showing bug on iOS7/iPad

In iOS7 disabling the status bar is a bit more complex than it was in iOS6. (We have to add a row call it “View controller-based status bar appearance” and set it to boolean NO in the Target Info properties tab.)

Unfortunately, there’s also a bug on the iPad (up to 7.1 as of this writing) that makes the status bar visible again after the photo roll is shown. Luckily, there’s a pretty easy fix.

First, make sure your UIViewController subclass (the one that is already a UIImagePickerControllerDelegate) is a UINavigationControllerDelegate as well. (It should be anyway to get rid of the warnings in XCode.) Then add the following UINavigationControllerDelegate function to that subclass:

- (void)navigationController:(UINavigationController *)navigationController
      willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

That’s it!