Search code examples
iosobjective-cipaduiactionsheet

UIActionSheet displays normal the first time, incorrect the second time


I have a strange issue with one of my iPad apps.

When the app starts up, I can tap a bar button item to display a UIActionSheet, and the action sheet displays normally from the bar button item with all the button options and title. However, if I select an action from this sheet, it uses presentViewController to show another very simple view controller, and when that view controller dismisses itself, if I tap on the same bar button item as before I get an action sheet that is not correct. Here is what the action sheet popover looks like:

enter image description here

The height of the action sheet is correct for the number of options that the action sheet is supposed to have, but it is like the title and all the button text are empty or nil. However, after I create the action sheet, I log the number of buttons and button text for each, and everything looks the same from the first time to the second time.

I am on the latest Xcode and SDK, and the app is targeting iOS 5.0 or newer. Any ideas as to what is going on?

EDIT: Here is some code. There may be some anomalies (syntactical and formatting wise) as I had to chop out a bunch of code that is not pertinent to this issue.

The IBAction for the maintenance button press:

-(IBAction) cmdMaintenance_Click:(id)sender
{
    self.maintenanceActionSheet = [[[UIActionSheet alloc] initWithTitle:@"Title"
                                                       delegate:self 
                                              cancelButtonTitle:@"Cancel"
                                         destructiveButtonTitle:nil
                                              otherButtonTitles:@"Backup", @"About", nil] autorelease];
    _maintenanceActionSheet.actionSheetStyle = UIActionSheetStyleDefault;
    _maintenanceActionSheet.tag = MAINTENANCE_OPTIONS;
    NSLog(@"Number of buttons: %d", _maintenanceActionSheet.numberOfButtons);
    for (int idx = 0; idx < _maintenanceActionSheet.numberOfButtons; idx++)
    {
        NSLog(@"Sheet button %d: %@", (idx + 1), [_maintenanceActionSheet buttonTitleAtIndex:idx]);
    }

    [_maintenanceActionSheet showFromBarButtonItem:cmdMaintenance animated:NO];
}

And the action sheet delegate:

-(void)actionSheet:(UIActionSheet*)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if(buttonIndex != [actionSheet cancelButtonIndex])
    {
            if(buttonIndex == OPTIONS_ABOUT)
            {
                if(aboutView == nil)
                {
                    aboutView = [[AboutViewController alloc] initWithNibName:@"AboutView-iPad" bundle:nil];
                    aboutView.title = [MyAppDelegate translateString:@"About"];
                }

                [self presentViewController:aboutView animated:YES completion:nil];
            }
    }
}

And in my About view controller, the Done button code:

-(IBAction)done:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

EDIT 2: One final note... If I comment out the call to presentViewController with aboutView, the action sheet comes back correctly.

EDIT 3: The question here comes down to this... What in the world could possibly cause the UIActionSheet to show a pop up like what I am seeing? My main view controller has other areas that display a UIActionSheet to ask for user feedback (such as deleting a customer), and these other areas show the same behavior as the Maintenance button, namely a really vertically thin action sheet.

EDIT 4: I put this extra code in my view controller in an attempt to get more information about what is going on (and to attempt to influence the size of the action sheet):

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
    NSLog(@"willPresentActionSheet with frame %@ and bounds %@", NSStringFromCGRect(actionSheet.frame),
          NSStringFromCGRect(actionSheet.bounds));

    CGRect rect = actionSheet.frame;
    rect.size.width = 400.0;
    actionSheet.frame = rect;
}

- (void)didPresentActionSheet:(UIActionSheet *)actionSheet
{
    NSLog(@"didPresentActionSheet with frame %@ and bounds %@", NSStringFromCGRect(actionSheet.frame),
          NSStringFromCGRect(actionSheet.bounds));
}

The attempt to change the frame of the action sheet has no effect of course, and here is the output in the console from the above:

2013-07-15 19:32:58.662 MyApp[12953:907] willPresentActionSheet with frame {{0, 0}, {272, 341}} and bounds {{0, 0}, {272, 341}}
2013-07-15 19:32:58.677 MyApp[12953:907] didPresentActionSheet with frame {{0, 0}, {272, 327}} and bounds {{0, 0}, {272, 327}}
2013-07-15 19:33:08.075 MyApp[12953:907] willPresentActionSheet with frame {{0, 0}, {0, 324}} and bounds {{0, 0}, {0, 324}}
2013-07-15 19:33:08.080 MyApp[12953:907] didPresentActionSheet with frame {{0, 0}, {0, 310}} and bounds {{0, 0}, {0, 310}}

The first two lines are from when it is working correctly, and as you can see from the second two lines, the width of the action sheet is 0 for some reason.


Solution

  • Well, the crux of the biscuit (as it were) had to do with the self.window code in the application didFinishLaunchingWithOptions method. Once I switched this app over to set the window's root view controller instead of adding a view controller's view as a subview of the window, it started behaving much better.

    Once again, I should probably read my own blog once in a while...

    http://www.dosomethinghere.com/2012/09/24/the-app-delegates-uiwindow-is-finicky/