Как представить модальный контроллер вида с нестандартным размером в центре?

Я хочу представить модальный контроллер нестандартного размера с анимацией снизу. Я могу добиться этой анимации с ModalPresentationStyle в FormSheet, но это заставляет меня использовать размер по умолчанию, который составляет 540x620, и мой взгляд не подходит.

Как заставить выполнить аналогичный переход к представлению (контроллеру) произвольного размера, расположенному в центре экрана?

2 ответа

Решение

Я не нашел способа сделать это из самого модального контроллера, поэтому я создал класс и метод расширения:

public class ModalViewController : UIViewController
{
    public SizeF OriginalViewSize { get; private set; }

    void Initialize ()
    {
        ModalPresentationStyle = UIModalPresentationStyle.FormSheet;
    }

    public override void ViewDidLoad ()
    {
        OriginalViewSize = View.Bounds.Size;
        base.ViewDidLoad ();
    }

    public ModalViewController (IntPtr handle) : base (handle)
    {
        Initialize ();
    }

    public ModalViewController (string nibName, NSBundle bundle) : base (nibName, bundle)
    {
        Initialize ();
    }

    public ModalViewController () : base ()
    {
        Initialize ();
    }
}

public static class ModalViewControllerExtensions
{
    public static void PresentModalViewController (this UIViewController parent, ModalViewController target)
    {
        parent.PresentViewController (target, true, null);

        target.View.Superview.AutoresizingMask = UIViewAutoresizing.FlexibleMargins;
        target.View.Superview.Frame = new RectangleF (PointF.Empty, target.OriginalViewSize);
        target.View.Superview.Center = UIScreen.MainScreen.Bounds.Center ().Rotate ();
    }
}

Это примерно, как я использую это:

this.PresentModalViewController (
    new PublishModalViewController (Item, HandlePublishAction)
);

Удобно, что мне не нужно явно указывать размер, потому что он использует границы корневого представления из компоновщика интерфейса. Я не уверен, как это реагирует на автоматическое вращение, может потребоваться некоторая настройка. Я также использую два метода расширения:

public static PointF Rotate (this PointF pt)
{
    return new PointF (pt.Y, pt.X);
}

public static PointF Center (this RectangleF rect)
{
    return new PointF (
        (rect.Right - rect.Left) / 2.0f,
        (rect.Bottom - rect.Top) / 2.0f
        );
}

И это все.

Более простой способ заключается в следующем

Представьте модальный контроллер вида в виде листа формы, а в модальный контроллер вида добавьте:

public override void ViewWillLayoutSubviews ()
{
    base.ViewWillLayoutSubviews ();
    this.View.Superview.Bounds = new RectangleF (0, 0, 900, 700);
}

Важно установить желаемую ширину и высоту, если вы не хотите, чтобы ios назначал размер листа формы по умолчанию

Обновление: по крайней мере, в ios 8 есть ситуации, когда приведенное выше решение вызывает бесконечный цикл. Кажется, что в некоторых ситуациях (например, при наличии встроенного веб-просмотра в модальном представлении и постукивании в некотором HTML-тексте ввода) изменение границ суперпредставления вызывает макет в модальном представлении, что приводит к бесконечному циклу и зависанию приложения. Но в ios 8 вы можете просто установить свойство PrefferedSize для достижения того же эффекта.

Другие вопросы по тегам