MvvmCross MvxFormFactorSpecific iPad/iPhone Attrib

2019-07-02 03:30发布

问题:

I have both iPhone and iPad specific view controllers which have MvxFormFactorSpecific(MvxTouchFormFactor.Phone) and MvxFormFactorSpecific(MvxTouchFormFactor.Pad) attributes, respectively. When the app is run on an iPad, the correct view is found and instantiated. However, when the app is run on a 4" iPhone, it throws an exception saying the "Could not find view for...". So is this a bug or am I doing something wrong?

Also, does MvxTouchFormFactor.Phone defaultly target 4" iPhones or do they need to be explicitly targeted with MvxTouchFormFactor.TallPhone?

回答1:

The implementation of this functionality is in:

  • https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Touch/Platform/MvxTouchPlatformProperties.cs
  • https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Touch/Views/MvxFormFactorSpecificAttribute.cs

The form factor itself is defined as:

    public MvxTouchFormFactor FormFactor
    {
        get
        {
            switch (UIDevice.CurrentDevice.UserInterfaceIdiom)
            {
                case UIUserInterfaceIdiom.Phone:
                    if (UIScreen.MainScreen.Bounds.Height*UIScreen.MainScreen.Scale >= 1136)
                        return MvxTouchFormFactor.TallPhone;

                    return MvxTouchFormFactor.Phone;

                case UIUserInterfaceIdiom.Pad:
                    return MvxTouchFormFactor.Pad;

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }

So - you can see that Phone is not currently the same as TallPhone


I suspect that your easiest way forwards here is probably to write your own conditional attribute - this is pretty easy to do - just look at how MvxFormFactorSpecificAttribute is defined and use it as the basis for your own attribute:

[AttributeUsage(AttributeTargets.Class)]
public class MyFormFactorSpecificAttribute
    : MvxConditionalConventionalAttribute
{
    public override bool IsConditionSatisfied
    {
        get
        {
            // put your logic here - could use Mvx.Resolve<IMvxTouchPlatformProperties>()
            return TODO;
        }
    }
}

If you think your attribute would be good for other users, I'd definitely be open to potential pull requests back to MvvmCross here for improvements.


Alternatively, you could simply mark your conflicting views as Unconventional and could manually add them to the View-ViewModel lookup during Setup


Sorry there is some confusion in this area. e.g. we've already marked MvxTouchPlatformProperties as obsolete as we do anticipate/hope that this sort of functionality will be replaced by CrossCore functionality at some point in the future.