问题
I am working on an app which was previously developed without using Storyboards, i.e. all the views were created in code. So as per this link, I am trying to pass a custom MvxTouchViewsContainer to MvxTouchSetup.CreateTouchViewsContainer.
protected override IMvxTouchView CreateViewOfType(Type viewType, MvxViewModelRequest request)
{
UIStoryboard storyboard;
try
{
storyboard = UIStoryboard.FromName(viewType.Name, null);
}
catch (Exception)
{
try {
storyboard = UIStoryboard.FromName("MainStoryBoard_iPhone", null);
}
catch (Exception) {
return base.CreateViewOfType (viewType, request);
}
}
IMvxTouchView resultView = null;
try {
resultView = (IMvxTouchView) storyboard.InstantiateViewController(viewType.Name);
} catch(Exception) {
resultView = base.CreateViewOfType (viewType, request);
}
return resultView;
}
Basically I try to find a storyboard if present, else I fallback to loading the view from code. The try - catch exceptions works fine in the simulator. However, the exceptions are not getting caught when running on an actual iOS Device and the app is crashing.
I get a MonoTouch.Foundation.MonoTouchException which contains NSInvalidArgumentException which basically is expected because, some views may not have a storyboard associated with them.
Is this a Xamarin bug?
回答1:
Using a custom attribute works better than the try/catch-method:
public class FromStoryboardAttribute : Attribute
{
public string StoryboardName { get; set; }
public FromStoryboardAttribute(string storyboardName = null)
{
StoryboardName = storyboardName;
}
}
Here is the StoryBoardContainer:
public class StoryBoardContainer : MvxTouchViewsContainer
{
protected override IMvxTouchView CreateViewOfType(Type viewType, MvxViewModelRequest request)
{
var storyboardAttribute = viewType.GetCustomAttribute<FromStoryboardAttribute>();
if (storyboardAttribute != null) {
var storyboard = UIStoryboard.FromName(storyboardAttribute.StoryboardName ?? viewType.Name, null);
var viewController = storyboard.InstantiateViewController(viewType.Name);
return (IMvxTouchView) viewController;
}
return base.CreateViewOfType(viewType, request);
}
}
Usage:
// Will look for a UIViewController with identifier "MyView" inside a Storyboard named "MyView.storyboard"
[FromStoryboard]
public class MyView : MvxViewController
{
public MyView(IntPtr handle) : base(handle) {}
}
// Will look for a UIVIewController with identifier "MyOtherViewInSameStoryboard" inside a Storyboard named "MyView.storyboard"
[FromStoryboard(StoryboardName = "MyView")]
public class MyOtherViewInSameStoryboard : MvxViewController
{
public MyOtherViewInSameStoryboard(IntPtr handle) : base(handle) {}
}
来源:https://stackoverflow.com/questions/28598392/monotouch-exception-not-getting-caught-on-device