5
votes

My app has one view controller that cannot change orientation. Think of it as a playing field that needs to stay fixed in place.

I now want to put up a UIActionSheet, but given the way the user is holding the device, I'd like to match the sheet to the orientation.

It seems that the UIActionSheet, unlike, say, the MFComposerViewController, doesn't get its orientation from the StatusBar, which I am rotating based on orientation, but gets its orientation from the underlying view controller. In other words, the UIActionSheet comes up in portrait orientation, regardless of how the device is being held.

I have tried:

CGAffineTransform   t = CGAffineTransformMakeRotation(lastUIAngle);
[actionSheet setTransform:t];
if (UIInterfaceOrientationIsLandscape(lastOrientation))
    actionSheet.frame = CGRectMake(0, 0, 480, 320);
else 
    actionSheet.frame = CGRectMake(0, 0, 320, 480);
actionSheet.center = self.view.center;

And I manage to get the right orientation, but the resulting action sheet comes up from the portrait side, and is sized as if it were still in portrait orientation. The action sheet's frame is calculated based on the number of buttons, etc.

Has anyone managed to force UIActionSheet to properly display in a specified orientation?

(I also tried creating a new view, which was transformed and had the correct size, but UIActionSheet ignored it. What remains left is to create a new UIViewController which auto rotates, and have UIActionSheet be a child of it. However, that means that my playing field gets completely obscured by the new view controller.)

2

2 Answers

7
votes

Turns out that the answer was pretty simple. Add this code to force UIActionSheets to whatever orientation you'd like:

tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
tempView.transform = CGAffineTransformMakeRotation(lastUIAngle);
tempView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view.window addSubview:tempView];

UIActionSheet *actionSheet = ...

[actionSheet showInView:tempView];

lastUIAngle is a multiple of pi/2, which, in this case, I had saved from the last time the orientation was changed.

0
votes

Check this alternative -> JonasGessner/JGActionSheet if you don't mind the basic layout, or you can modify it in the src code.

This worked for me on iOS 8.0.2. Just like below:

  1. Include it in your project.

Copy JGActionSheet.h and JGActionSheet.m to you project

  1. Import it where you're going to use an action sheet.

#import "JGActionSheet.h"

  1. Use it.

Sample Code:

JGActionSheetSection *menuSection = [JGActionSheetSection sectionWithTitle:nil message:@"Select Food" buttonTitles:@[@"Hamburger", @"Toast", @"Rice"] buttonStyle:JGActionSheetButtonStyleDefault];
[menuSection setButtonStyle:JGActionSheetButtonStyleRed forButtonAtIndex:0];

JGActionSheetSection *cancelSection = [JGActionSheetSection sectionWithTitle:nil message:nil buttonTitles:@[@"Cancel"] buttonStyle:JGActionSheetButtonStyleCancel];

NSArray *sections = @[menuSection, cancelSection];
JGActionSheet *sheet = [JGActionSheet actionSheetWithSections:sections];

[sheet setButtonPressedBlock:^(JGActionSheet *sheet, NSIndexPath *indexPath) {
    [sheet dismissAnimated:YES];
}];

// Set specific orientation to action sheet
sheet.transform = CGAffineTransformMakeRotation(M_PI);

[sheet showInView:self.view animated:YES];