4

I'm developing a Universal app in iOS8.1.

I would like the app to always appear in Portrait Orientation.

I have forced it by adding the following code. This is working.

In AppDelegate:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        // Override point for customization after application launch.

        let value = UIInterfaceOrientation.Portrait.rawValue
        UIDevice.currentDevice().setValue(value, forKey: "orientation")

        return true
    }

I use the following subclass for all my View Controllers:

class PortraitViewController: UIViewController {

    override func shouldAutorotate() -> Bool {
        return true
    }

    override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
        return UIInterfaceOrientation.Portrait
    }

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.rawValue)
    }

}

Then however, I added an SLComposeViewController to my app so users can post to Facebook. If the user opens this SLComposeViewController while their device is in landscape, the SLComposeViewController takes over and rotates the screen, including all other ViewControllers that are already presented.

I would like to force the SLComposeViewController to always stay in Portrait Orientation, but can't figure out how to get it to work.

Can anyone help me?

This is the code I use to open the SLComposeViewController.

func pressFacebook(){
    if PortraitSLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook) {
        var facebookSheet: SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)

        facebookSheet.setInitialText("My Status!")
        self.presentViewController(facebookSheet, animated: true, completion: nil)
        facebookSheet.addURL(NSURL(string: "www.blahblah.com"))
        facebookSheet.addImage(UIImage(named: "fb.jpg"))

    }
}

Thanks in advance!

2 Answers2

5

I was able to solve this by subclassing SLComposeViewController

import Social
import UIKit

class ComposeViewController: SLComposeViewController {

    override func shouldAutorotate() -> Bool {
        return true
    }

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.rawValue)
    }

}
Nick Lee
  • 127
  • 2
  • 9
2

You can either subclass SLComposeViewController or simply extend it.

Here's how I fixed the issue in a generalizable way. Both UIActivityViewController and the SLComposeViewController that it presents check their presenting view controllers to determine their autorotation configurations using the following category extensions:

@implementation UIActivityViewController (FixAutoRotation)

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.presentingViewController.preferredInterfaceOrientationForPresentation;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.presentingViewController.supportedInterfaceOrientations;
}

- (BOOL)shouldAutorotate {
    return false;
}

@end


@implementation SLComposeViewController (FixAutoRotation)

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.presentingViewController.preferredInterfaceOrientationForPresentation;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.presentingViewController.supportedInterfaceOrientations;
}

- (BOOL)shouldAutorotate {
    return false;
}

@end

This code is in Objective-C but should be trivial to change to Swift. Note that you would have to force-unwrap presentingViewController under the assumption that these view controllers are ALWAYS presented modally.

Ilias Karim
  • 4,798
  • 3
  • 38
  • 60