无法使用 iOS 中的故事板让 MvvmCross 工作
Cannot get MvvmCross using storyboards in iOS to work
我正在尝试使用故事板编写一个 MvvmCross 应用程序。我知道有类似的问题,但我已经遵循了解决方案,但我无法让它工作。我已经引用了我在这个问题中尝试过的解决方案之一。
我将从一开始就解释我所做的事情,希望这有助于诊断我的问题
- 使用 Visual Studio 中的通用 iOS 单视图应用创建项目。
- 我进行标准的 MvvmCross 设置、添加 nuget、更新 AppDelegate 等
- 我编译它。
- 我在 iPhone 故事板中添加了一个新的 ViewController。我称之为登录ViewController。我将 Class、Storyboard ID 和 Restoration ID 设置为 LogonViewController。生成登录ViewController class。我将其更改为从 MvxViewController
派生
- 我将入口箭头从 RootViewController(故事板上最初创建时的视图控制器)移至指向 LogonViewController。我把 RootViewController 留在故事板
我更改 LogonViewController class 派生自 MvxViewController 并将 Register 属性设置为 LogonView eg
[Register ("LogonView")]
partial class LogonViewController
我在登录ViewController中添加了一个标签,只是为了显示。
我根据
中的 post 创建了一个派生自 MvxTouchViewsContainers 的自定义容器
MVVMCross support for Xamarin.iOS Storyboards
问题是,当在自定义容器中调用覆盖方法(如下所示)时,我得到一个无效的转换异常,因为它无法将 UIKit.UIViewController 转换为 IMvxTouchView
我也遇到算术溢出异常
protected override IMvxTouchView CreateViewOfType(Type viewType, MvxViewModelRequest request)
{
return (IMvxTouchView)UIStoryboard.FromName("MyStoryBoard", null)
.InstantiateViewController(viewType.Name);
}
在跟踪日志中我得到以下错误
2015-01-28 18:12:09.833 MyApp[3743:68927] mvx:Diagnostic: 8.61 Setup: LastChance start
[0:] mvx:Diagnostic: 8.61 Setup: LastChance start
[0:]
2015-01-28 18:12:10.247 MyApp[3743:68927] mvx:Diagnostic: 9.05 Setup: Secondary end
[0:] mvx:Diagnostic: 9.05 Setup: Secondary end
[0:]
2015-01-28 18:12:10.647 MyApp[3743:68927] mvx:Diagnostic: 9.43 Showing ViewModel LogonViewModel
[0:] mvx:Diagnostic: 9.43 Showing ViewModel LogonViewModel
[0:]
2015-01-28 18:12:11.049 MyApp[3743:68927] TouchNavigation:Diagnostic: 9.83 Navigate requested
[0:] TouchNavigation:Diagnostic: 9.83 Navigate requested
2015-01-28 18:12:11.254 MyApp[3743:68927] Unknown class LogonViewController in Interface Builder file.
2015-01-28 18:12:23.962 MyApp[3743:68927] -[UIViewController bottomLayoutGuide]: guide not available before the view controller's view is loaded
System.OverflowException: Arithmetic operation resulted in an overflow.
at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
System.OverflowException: Arithmetic operation resulted in an overflow.
at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
System.OverflowException: Arithmetic operation resulted in an overflow.
at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
Unhandled Exception:
System.InvalidCastException: Unable to cast object of type 'UIKit.UIViewController' to type 'Cirrious.MvvmCross.Touch.Views.IMvxTouchView'.
我不知道我在这里做错了什么。有没有人有任何想法?这是安装的软件版本
MvvmCross 3.5.0
Visual Studio 2012 更新 4,
Xamarin 通用安装程序 v3.5.0.0
Xamarin Studio 5.7 v5.7.0.661
Xamarin v3.9.236.0
更新
我听取了 EShy 的建议并添加了控制器并将其命名为 LogonView,但是我仍然遇到未构建 LogonViewModel 的问题。日志如下所示。有什么想法吗?
2015-01-29 11:31:33.579 MyApp[12631:273902] mvx:Diagnostic:286.77 Message = [Failed to construct and initialize ViewModel for type MyApp.Core.ViewModels.LogonViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information]
[0:] mvx:Diagnostic:286.77 Message = [Failed to construct and initialize ViewModel for type MyApp.Core.ViewModels.LogonViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information]
[0:]
2015-01-29 11:31:33.985 MyApp[12631:273902] mvx:Diagnostic:287.17 Stack Trace = [ at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled
[0:] mvx:Diagnostic:287.17 Stack Trace = [ at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
at (wrapper delegate-invoke) <Module>:invoke_void_object_EventArgs (object,System.EventArgs)
at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0
at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46
at MyApp.iOS.Application.Main (System.String[] args) [0x00002] in c:\MyApp.iOS\Main.cs:21 ]
(System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
at (wrapper delegate-invoke) <Module>:invoke_void_object_EventArgs (object,System.EventArgs)
at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0
at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46
at MyApp.iOS.Application.Main (System.String[] args) [0x00002] in c:\MyApp\
MyApp.iOS\Main.cs:21 ]
[0:]
2015-01-29 11:31:34.393 MyApp[12631:273902] mvx:Diagnostic:287.58 Inner Exception message = [Problem creating viewModel of type LogonViewModel]
[0:] mvx:Diagnostic:287.58 Inner Exception message = [Problem creating viewModel of type LogonViewModel]
您应该在故事板 LogonView 中命名您的 viewcontroller 而不是 LogonViewController。这就是 MvvmCross 正在寻找的viewType.Name。
问题是注入 LogonViewModel 的服务使用了 MvvmCross Messenger 插件。我没有通过 nuget 添加插件到项目中。通知我这一点的异常是内部异常的内部异常。我应该挖得更深。再次感谢 Stuart 的帮助和 MvvmCross 的总体优势。还要感谢 EShy 提供的命名帮助。
我正在尝试使用故事板编写一个 MvvmCross 应用程序。我知道有类似的问题,但我已经遵循了解决方案,但我无法让它工作。我已经引用了我在这个问题中尝试过的解决方案之一。
我将从一开始就解释我所做的事情,希望这有助于诊断我的问题
- 使用 Visual Studio 中的通用 iOS 单视图应用创建项目。
- 我进行标准的 MvvmCross 设置、添加 nuget、更新 AppDelegate 等
- 我编译它。
- 我在 iPhone 故事板中添加了一个新的 ViewController。我称之为登录ViewController。我将 Class、Storyboard ID 和 Restoration ID 设置为 LogonViewController。生成登录ViewController class。我将其更改为从 MvxViewController 派生
- 我将入口箭头从 RootViewController(故事板上最初创建时的视图控制器)移至指向 LogonViewController。我把 RootViewController 留在故事板
我更改 LogonViewController class 派生自 MvxViewController 并将 Register 属性设置为 LogonView eg
[Register ("LogonView")] partial class LogonViewController
我在登录ViewController中添加了一个标签,只是为了显示。
我根据
中的 post 创建了一个派生自 MvxTouchViewsContainers 的自定义容器
MVVMCross support for Xamarin.iOS Storyboards
问题是,当在自定义容器中调用覆盖方法(如下所示)时,我得到一个无效的转换异常,因为它无法将 UIKit.UIViewController 转换为 IMvxTouchView
我也遇到算术溢出异常
protected override IMvxTouchView CreateViewOfType(Type viewType, MvxViewModelRequest request)
{
return (IMvxTouchView)UIStoryboard.FromName("MyStoryBoard", null)
.InstantiateViewController(viewType.Name);
}
在跟踪日志中我得到以下错误
2015-01-28 18:12:09.833 MyApp[3743:68927] mvx:Diagnostic: 8.61 Setup: LastChance start
[0:] mvx:Diagnostic: 8.61 Setup: LastChance start
[0:]
2015-01-28 18:12:10.247 MyApp[3743:68927] mvx:Diagnostic: 9.05 Setup: Secondary end
[0:] mvx:Diagnostic: 9.05 Setup: Secondary end
[0:]
2015-01-28 18:12:10.647 MyApp[3743:68927] mvx:Diagnostic: 9.43 Showing ViewModel LogonViewModel
[0:] mvx:Diagnostic: 9.43 Showing ViewModel LogonViewModel
[0:]
2015-01-28 18:12:11.049 MyApp[3743:68927] TouchNavigation:Diagnostic: 9.83 Navigate requested
[0:] TouchNavigation:Diagnostic: 9.83 Navigate requested
2015-01-28 18:12:11.254 MyApp[3743:68927] Unknown class LogonViewController in Interface Builder file.
2015-01-28 18:12:23.962 MyApp[3743:68927] -[UIViewController bottomLayoutGuide]: guide not available before the view controller's view is loaded
System.OverflowException: Arithmetic operation resulted in an overflow.
at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
System.OverflowException: Arithmetic operation resulted in an overflow.
at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
System.OverflowException: Arithmetic operation resulted in an overflow.
at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
Unhandled Exception:
System.InvalidCastException: Unable to cast object of type 'UIKit.UIViewController' to type 'Cirrious.MvvmCross.Touch.Views.IMvxTouchView'.
我不知道我在这里做错了什么。有没有人有任何想法?这是安装的软件版本
MvvmCross 3.5.0 Visual Studio 2012 更新 4, Xamarin 通用安装程序 v3.5.0.0 Xamarin Studio 5.7 v5.7.0.661 Xamarin v3.9.236.0
更新
我听取了 EShy 的建议并添加了控制器并将其命名为 LogonView,但是我仍然遇到未构建 LogonViewModel 的问题。日志如下所示。有什么想法吗?
2015-01-29 11:31:33.579 MyApp[12631:273902] mvx:Diagnostic:286.77 Message = [Failed to construct and initialize ViewModel for type MyApp.Core.ViewModels.LogonViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information]
[0:] mvx:Diagnostic:286.77 Message = [Failed to construct and initialize ViewModel for type MyApp.Core.ViewModels.LogonViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information]
[0:]
2015-01-29 11:31:33.985 MyApp[12631:273902] mvx:Diagnostic:287.17 Stack Trace = [ at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled
[0:] mvx:Diagnostic:287.17 Stack Trace = [ at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
at (wrapper delegate-invoke) <Module>:invoke_void_object_EventArgs (object,System.EventArgs)
at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0
at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46
at MyApp.iOS.Application.Main (System.String[] args) [0x00002] in c:\MyApp.iOS\Main.cs:21 ]
(System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
at (wrapper delegate-invoke) <Module>:invoke_void_object_EventArgs (object,System.EventArgs)
at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0
at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46
at MyApp.iOS.Application.Main (System.String[] args) [0x00002] in c:\MyApp\
MyApp.iOS\Main.cs:21 ]
[0:]
2015-01-29 11:31:34.393 MyApp[12631:273902] mvx:Diagnostic:287.58 Inner Exception message = [Problem creating viewModel of type LogonViewModel]
[0:] mvx:Diagnostic:287.58 Inner Exception message = [Problem creating viewModel of type LogonViewModel]
您应该在故事板 LogonView 中命名您的 viewcontroller 而不是 LogonViewController。这就是 MvvmCross 正在寻找的viewType.Name。
问题是注入 LogonViewModel 的服务使用了 MvvmCross Messenger 插件。我没有通过 nuget 添加插件到项目中。通知我这一点的异常是内部异常的内部异常。我应该挖得更深。再次感谢 Stuart 的帮助和 MvvmCross 的总体优势。还要感谢 EShy 提供的命名帮助。