How to present a modal view controller with custom size in center?

两盒软妹~` 提交于 2019-11-28 03:19:16

问题


I want to present a custom-sized modal view controller with animation from the bottom. I can achieve this animation with ModalPresentationStyle to FormSheet, but it forces me to use the default size which is 540x620 and my view doesn't fit.

How do I make perform a similar transition to an arbitrarily sized view (controller) placed in center of the screen?


回答1:


I didn't find a way to do it from the modal controller itself so I created a class and an extension method:

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 is roughly how I use it:

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

It is convenient that I don't need to specify the size explicitly because it uses root View's bounds from the interface builder. I'm not sure how this reacts to autorotate, it may need some tuning. I'm also using two extension methods here:

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
        );
}

And this is it.




回答2:


An easier way is the following

Present the modal view controller as a form sheet and in the modal view controller add:

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

It is important to set the desired width and height if you don't want ios to assign the default form sheet size

Update: In ios 8 at least there are some situation when the solution above triggeres an infinte loop. It seems that in some situations (like when having an embedded webview in the modal view and tapping in some html input text) changing the superview bounds triggers layout on the modal view resulting in an infinite loop and freeze of the app. But in ios 8 you can simply set the PrefferedSize property to achieve the same effect.



来源:https://stackoverflow.com/questions/14048301/how-to-present-a-modal-view-controller-with-custom-size-in-center

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!