如何在 iOS 中使用没有故事板的 MvvmCross?

Posted

技术标签:

【中文标题】如何在 iOS 中使用没有故事板的 MvvmCross?【英文标题】:How to use MvvmCross without storyboards in iOS? 【发布时间】:2020-12-29 07:02:00 【问题描述】:

当我使用 MvvmCross 5 时,我对所有视图进行了编码,并通过在我的 AppDelegate 中写下这段代码来避免在我的 ios 应用程序中使用故事板:

[Register("AppDelegate")]
public class AppDelegate : MvxApplicationDelegate

    private MvxIosViewPresenter viewPresenter;

    public override UIWindow Window
    
        get;
        set;
    

    /// <summary>
    /// MvvmCross Mods:
    /// - Creates a new presenter, which determines how Views are shown
    /// - This example uses a standard presenter.
    /// </summary>
    /// <param name="application"></param>
    /// <param name="launchOptions"></param>
    /// <returns></returns>
    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    
        // create a new window instance based on the screen size
        Window = new UIWindow(UIScreen.MainScreen.Bounds);

        // MvvmCross Mod Start---------------------------------------------

        // This class will determine how Views are shown
        this.viewPresenter = new MvxIosViewPresenter(this, Window);//new ViewPresenter(Window);

        // Init the Setup object, which initializes App.cs
        var setup = new Setup(this, this.viewPresenter);
        setup.Initialize();

        //this.viewPresenter.PresentModalViewController(new ListenViewController(), true);

        // Use IoC to find and start the IMvxAppStart object
        var startup = Mvx.Resolve<IMvxAppStart>();
        startup.Start();

        // MvvmCross Mod End--------------------------------------------------

        // make the window visible
        Window.MakeKeyAndVisible();

        return true;
    

public class Setup : MvxIosSetup

    public Setup(MvxApplicationDelegate appDelegate, IMvxIosViewPresenter presenter)
        : base(appDelegate, presenter)
    
    

    protected override IMvxApplication CreateApp()
    
        return new Core.App();
    

    protected override IMvxTrace CreateDebugTrace()
    
        return new DebugTrace();
    

但在 MvvmCross 6.4.2 中,MvxIosSetup 没有采用 2 个参数的基本构造函数。相反,我有:

[Register(nameof(AppDelegate))]
public partial class AppDelegate : MvxApplicationDelegate<Setup, App>



public class Setup : MvxIosSetup<App>


如何配置它,以便在没有情节提要的情况下编写视图?

编辑

我使用 MvvmCross 7 创建了一个带有 1 个视图模型/控制器的非常小的示例应用程序。ViewDidLoad 方法永远不会在我的 MainViewController 中被调用。有人可以告诉我为什么吗?我把我的代码放在这里:

https://github.com/sinight95/TestApp/tree/main/TestApp

【问题讨论】:

您的 ViewModel 项目决定了首先显示哪个页面。你不需要执行你正在做的旧事情。查看 MvvmCross 示例,尤其是 TipCalc 和 StarWars 示例 github.com/MvvmCross/MvvmCross-Samples 另外,您不必将故事板用作视图,您可以使用 XIB,也可以只使用从没有 XIB 或 Designer 类的 MvxViewController 继承的普通 C# 类。您只需确保将 ViewModel 类型传入 MvxViewController 如果我删除故事板文件,iOS 应用程序将在启动时崩溃并显示消息Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Could not find a storyboard named 'Main' in bundle NSBundleandroid版本虽然可以。我的 iOS 项目中一定缺少配置? 查看您的 info.plist 文件。您可能正在调用要启动的故事 bord 文件。 我在 info.plist 文件中没有找到任何内容。你能看看我的编辑并验证我的代码吗?这是 MvvmCross 7 中最小的 iOS 应用程序。我将不胜感激! 【参考方案1】:

无论您是否展示故事板,Setup.cs 和 AppDelegate.cs 文件都没有任何关系。这通常取决于您将哪些 Presentation Attributes 应用于 ViewController。

但是,Info.plist 中设置了一些内容,这些内容会改变 MvvmCross 期望的设置方式。

现在,在您放在 GitHub 上的示例应用程序中,您可以执行以下操作以使其不使用情节提要:

    删除Main.storyboard 在 Info.plist 中将主界面设置为(无) 在 Info.plist 中将启动图像设置为 LaunchScreen.storyboard 删除 Info.plist 中的场景委托内容 删除MainViewController中的构造函数

这里的主要问题是,通过提供此构造函数,您实际上是在告诉 iOS ViewController 有一个故事板:

public MainViewController() : base(nameof(MainViewController), null)


还通过 Info.plist 告诉 iOS 使用故事板和所有场景委托的东西。

我创建了一个 PR,显示需要更改哪些内容才能使其在没有存储板的情况下运行,并显示您在 ViewController 上设置的蓝色背景颜色。

https://github.com/sinight95/TestApp/pull/1

【讨论】:

以上是关于如何在 iOS 中使用没有故事板的 MvvmCross?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 的基于故事板的应用程序中使用我的视图控制器

swift 没有故事板的iOS项目。 AppDelegate.swift

没有 Xib 和故事板的旧应用程序。使ios9兼容

iOS 添加视图:来自故事板的广告视图,无限制

在 Xcode 5 中修改故事板后如何同步本地化故事板的字符串

如何在 XCode 中预览故事板的不同视图控制器