Search code examples
ipadmonoxamarin.iosuiactionsheet

Monotouch - UIActionSheet not displaying correctly on iPad


I have a UIActionSheet that works just fine on the iPhone simulator. It is presented when the user touches a UIButton.

Using the iPad, I believe UIActionSheets are wrapped into a UIPopupController.

When I call the same code using the iPad simulator, I get a thin "line" displayed, which looks like a UIPopupController (you can see the small arrow that usually points to a control). None of the content can be seen.

What is the correct way to use a UIActionSheet using the iPad with MonoTouch? Here is a bit of sample code I have been testing with - creating the UIActionSheet:

var actionSheet = new UIActionSheet () { Style = UIActionSheetStyle.BlackTranslucent };
        actionSheet.Frame = actionSheetFrame;
        actionSheet.Clicked += (s, e) => { Console.WriteLine ("Clicked on item {0}", e.ButtonIndex); };
actionSheet.AddSubview (doneButton);

Then, I am showing the actionsheet by calling the following from a button:

btnSay.TouchUpInside += (sender, e) => {
            actionSheet.ShowFrom(tmpBtn.Frame, tmpView, false);
        };

I get something like the attached screenshot when using the iPad simulator.

iPad UIActionSheet example

For reference, here is what the UIActionSheet looks like when using the iPhone simulator.

iPhone UIActionSheet example

Note: The project is a universal single-view MonoTouch c# project.

Any pointers or help would be much appreciated!


Solution

  • I faced this same problem with a recent app I released to the app store.

    When you show a UIActionSheet on iPad, iOS wraps the UIActionSheet in a UIPopoverView.

    I used the following code to detect whether this is an iPad, and if it is, adjust the frame of the popover view:

    const int CHROMEWIDTHLEFT = 9;
    const int CHROMEWIDTHRIGHT = 8;
    const int MARGIN = 50;
    
    UIActionSheet _actionSheet;
    
    ...
    
    if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad) {
        var popover = _actionSheet.Superview.Superview;
        if (popover != null)
        {
            var x = _actionSheet.Frame.X + MARGIN;
            var y = (UIScreen.MainScreen.ApplicationFrame.Height - _actionSheet.Frame.Height) / 2;
            var width = _actionSheet.Frame.Width - (MARGIN * 2);
            var height = _actionSheet.Frame.Height;
    
            popover.Frame = new RectangleF (x, y, width, height);
            _actionSheet.Frame = new RectangleF (x, y, width - (CHROMEWIDTHLEFT + CHROMEWIDTHRIGHT), height - (CHROMEWIDTHLEFT + CHROMEWIDTHRIGHT));
        }
    }
    

    The example is based upon the Xamarin ActionSheet Date Picker here

    I have put these up as a Gist (Normal and DatePicker)