gpt4 book ai didi

ios - 单个 ViewModel 的多个 View (iOS)

转载 作者:行者123 更新时间:2023-11-29 12:27:48 24 4
gpt4 key购买 nike

我知道,为了实现这一点,我需要创建一个自定义演示者并通过覆盖 InitializeViewLookup 方法手动将 ViewModel 映射到我的 View 。我在 Android 上成功地做到了这一点,到目前为止它运行良好,但我似乎无法在 iOS 上做到这一点。这是我尝试过的:

public override void Show(MvxViewModelRequest request)
{
// check if there are any presentation values
if (request.PresentationValues != null)
{
// if yes, check if one of them is SelectedView
if (request.PresentationValues.ContainsKey(SingletonViewModelLocator.SelectedView))
{
UIViewController viewController;
switch (request.PresentationValues[SingletonViewModelLocator.SelectedView])
{
// The ViewModel requested the First View, load that one
case SingletonViewModelLocator.FirstViewValue:
viewController = new FirstView();
MasterNavigationController.PushViewController(viewController, true);
return;
// The ViewModel requested the Second View, load that one
case SingletonViewModelLocator.SecondViewValue:
viewController = new SecondView();
MasterNavigationController.PushViewController(viewController, true);
return;
// wrong view requested
default:
throw (new InvalidEnumArgumentException(request.PresentationValues[SingletonViewModelLocator.SelectedView] +
" does not exist."));
}
}
}
// otherwise run the default method which means 1 ViewModel is mapped to 1 View
base.Show(request);
}

这是InitializeViewLookup:

protected override void InitializeViewLookup()
{
var container = Mvx.Resolve<IMvxViewsContainer>();
container.Add(typeof(MainViewModel), typeof(MainView));
// TheViewModel is mapped to two Views
container.Add(typeof(TheViewModel), typeof(FirstView));
container.Add(typeof(TheViewModel), typeof(SecondView));
}

当导航发生时,这会在 Mvx 库中的 ViewDidLoad 方法中的某处产生“对象引用未设置为对象的实例”异常。

仅供引用,以下是我在 Android 上的操作方法,效果很好。

public override void Show(MvxViewModelRequest request)
{
// check if there are any presentation values
if (request.PresentationValues != null)
{
// if yes, check if one of them is SelectedView
if (request.PresentationValues.ContainsKey(SingletonViewModelLocator.SelectedView))
{
var activity = Activity;
Intent intent;
switch (request.PresentationValues[SingletonViewModelLocator.SelectedView])
{
// The ViewModel requested the First View, load that one
case SingletonViewModelLocator.FirstViewValue:
intent = new Intent(activity, typeof (FirstView));
Show(intent);
return;
// The ViewModel requested the Second View, load that one
case SingletonViewModelLocator.SecondViewValue:
intent = new Intent(activity, typeof (SecondView));
Show(intent);
return;
// wrong view requested
default:
throw (new InvalidEnumArgumentException(request.PresentationValues[SingletonViewModelLocator.SelectedView] +
" does not exist."));
}
}
}
// otherwise run the default method which means 1 ViewModel is mapped to 1 View
base.Show(request);
}

编辑

这是堆栈跟踪:

0x0 in Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel   
0x65 in Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel
0x13 in Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate
0xE in Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate
0x7 in Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled
0xB in Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise
0xD in Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad

0x2 in Demo.iOS.FirstView.ViewDidLoad at c:[path]\View\FirstView.cs:34,-1
0xA6 in UIKit.UIApplication.UIApplicationMain
0xB in UIKit.UIApplication.Main at /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62,4
0x3B in UIKit.UIApplication.Main at /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46,4
0x8 in Demo.iOS.Application.Main at c:[path]\Main.cs:17,-1

最佳答案

Mvx Touch 应用程序中的默认容器使用如下代码创建 View :

            CurrentRequest = request;
var viewType = GetViewType(request.ViewModelType);
if (viewType == null)
throw new MvxException("View Type not found for " + request.ViewModelType);

var view = CreateViewOfType(viewType, request);
view.Request = request;
return view;

来自 https://github.com/MvvmCross/MvvmCross/blob/1eeea41e110934e52bf7e6682d8751b885206844/Cirrious/Cirrious.MvvmCross.Touch/Views/MvxTouchViewsContainer.cs#L31

每个View然后加载/定位它自己的 ViewModel使用隐藏在 Request 中的说明.

如果Request为空,则 Mvx 默认采用一些启发式方法,以使用 View 创建一个基于约定类型的默认 ViewModel的类名。


对于您的情况,我认为最好的解决方案是设置 Request ViewController 上的属性 - 例如

                case SingletonViewModelLocator.SecondViewValue:
viewController = new SecondView() { Request = request };
MasterNavigationController.PushViewController(viewController, true);
return;

但是,您也可以通过在 SecondView 中提供提示来做到这一点关于预期的 ViewModel 类型......您可以通过覆盖 ViewModel 来做到这一点具有类型的属性,继承自 MvxViewController<T> ,通过为 View 模型类型 ( MvxViewFor ) 提供属性提示,或者在 Setup 期间添加一些特殊查找

请注意 - 你的问题还向我暗示你在 ViewModel 上做了一些单例魔术查找方面,因此您可能需要调整此答案以匹配任何内容......

关于ios - 单个 ViewModel 的多个 View (iOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28572962/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com