iOS 的 MvvmCross 对话框演示

MvvmCross Dialog Presentation for iOS

我有一个我编写的应用程序 运行 在 Android 平台上运行良好。我目前正在将它移植到 iOS,iOS 似乎缺少一个基本功能,或者我不知道如何让它工作。我需要能够不时弹出一个消息框。我将以下代码用于 Android.

我的ViewModel如下:

public class MessageDialogViewModel : MvxViewModel<string, MessageDialogViewModel.Result>
{
    public class Result
    {
        public Result(bool parm)
        {
            Success = parm;
        }

        public bool Success { get; set; }
    }

    private readonly IMvxNavigationService _navigationService;

    public MessageDialogViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService;

        CloseCommand = new MvxAsyncCommand(async () => await _navigationService.Close(this, new Result(true)));
    }

    public override System.Threading.Tasks.Task Initialize()
    {
        return base.Initialize();
    }

    public override void Prepare(string parm)
    {
        base.Prepare();
        Message = parm;
    }

    public IMvxAsyncCommand CloseCommand { get; private set; }

    private string _Message;
    public string Message
    {
        get
        {
            return _Message;
        }
        set
        {
            _Message = value;
            RaisePropertyChanged(() => Message);
        }
    }
}

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:background="@drawable/borderdoublewidth">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/TableHeaderTextView"
        local:MvxBind="Text Message" />
    <LinearLayout
        android:orientation="horizontal"
        android:gravity="right"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CLOSE"
            style="@style/DialogButton"
            local:MvxBind="Click CloseCommand" />
    </LinearLayout>
</LinearLayout>

Android 的视图是这样的:

[MvxDialogFragmentPresentation]
[Register(nameof(MessageDialogView))]
public class MessageDialogView : MvxDialogFragment<MessageDialogViewModel>
{
    public MessageDialogView()
    {
    }

    protected MessageDialogView(IntPtr javaReference, JniHandleOwnership transfer)
        : base(javaReference, transfer)
    {
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var ignore = base.OnCreateView(inflater, container, savedInstanceState);

        var view = this.BindingInflate(Resource.Layout.MessageDialogView, null);

        return view;
    }
}

这是我所有 Android 应用程序中的转到弹出功能。这很简单。我创建了一个 iOS 版本的视图,如下所示:

[MvxModalPresentation(WrapInNavigationController = false,
    ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve,
    ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen)]
class MessageDialogView : MvxViewController<MessageDialogViewModel>
{
    public override void ViewDidLoad()
    {
        View.BackgroundColor = UIColor.White;
        base.ViewDidLoad();

        var formView = new UIView();
        formView.BackgroundColor = UIColor.Black;

        var message = new UILabel() { Text = ViewModel.Message };
        formView.Add(message);
        message.TextColor = UIColor.White;
        message.Font = message.Font.WithSize(20f);

        var btnClose = new UIButton(UIButtonType.RoundedRect);
        btnClose.SetTitle("Close", UIControlState.Normal);
        btnClose.Font = btnClose.Font.WithSize(20f);
        btnClose.SetTitleColor(UIColor.Clear.FromHex(0x00D0F7), UIControlState.Normal);
        formView.Add(btnClose);

        var set = this.CreateBindingSet<MessageDialogView, MessageDialogViewModel>();
        set.Bind(btnClose).To(vm => vm.CloseCommand);
        set.Apply();

        View.Add(formView);

        View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

        View.AddConstraints(
            formView.AtLeftOf(View),
            formView.AtRightOf(View),
            formView.AtTopOfSafeArea(View),
            formView.AtBottomOf(View)
        );

        formView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

        formView.AddConstraints(
            message.AtTopOf(formView, 10f),
            message.WithSameCenterX(formView),

            btnClose.Below(message, 20f),
            btnClose.AtRightOf(formView)

            );

    }
}

这有效,但它并不是真正的弹出窗口。它覆盖了整个屏幕。我已经尝试了 ModalPresentationStyle 的其他选项,但无论如何对话框都以相同的方式运行。文档说其他选项只适用于 iPad,我正在为 iPhone 开发。我见过其他有小弹出对话框的应用程序。我查看了此处的代码 https://prin53.medium.com/pop-up-xamarin-e2d815441a54,该示例适用于他的特定目的,但是当我尝试使其适用于我的代码时,我收到一个“断言”错误,这对于我的水平来说非常模糊。似乎必须有一种方法可以弹出一个小对话框,而不必跳过这么多箍。有人可以帮忙吗?

谢谢, 吉姆

好的,这就是我所做的。它有点脏,但它有效。请不要笑。我创建了一个具有清晰背景的视图,并从中弹出了一个标准警报。我能够使用 Message 属性 并执行 CloseCommand,因此 MessageDialogViewModel 看到的与 Android 中看到的一样。这是:

[MvxModalPresentation(WrapInNavigationController = false,
    ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve,
    ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen)]
class MessageDialogView : MvxViewController<MessageDialogViewModel>
{
    public override void ViewDidAppear(bool animated)
    {
        base.ViewDidAppear(animated);

        View.BackgroundColor = UIColor.Clear;

        var okAlertController = UIAlertController.Create("", ViewModel.Message, UIAlertControllerStyle.Alert);

        okAlertController.AddAction(UIAlertAction.Create("Close", UIAlertActionStyle.Default, (handler) => ViewModel.CloseCommand.ExecuteAsync()));

        PresentViewController(okAlertController, true, null);
    }
}