【问题标题】:MvvmCross ViewModel transition from the leftMvvmCross ViewModel 从左侧过渡
【发布时间】:2014-10-10 10:04:20
【问题描述】:

我正在使用 MvvmCross 为 iOS 开发一个应用程序。在我的一个视图中,我有一些基本的报告数据显示在表格视图中。

当触摸表格行时,通过调用 ShowViewModel 并在 Dictionary 中传递一些参数来显示包含详细报告的新视图。这很好用。

当用户向左或向右滑动时,应用需要显示原始列表中下一个或上一个项目的详细报告。我通过更新一些参数并再次调用 ShowViewModel 来做到这一点。这背后的逻辑一切正常。

我的问题; ShowViewModel 对从右侧进入的新视图进行动画处理。当用户向左滑动时,这是完美的。然而,当向右滑动时,它似乎违反直觉。如何使 ShowViewModel 动画或从左侧过渡?

【问题讨论】:

    标签: ios xamarin.ios xamarin mvvmcross


    【解决方案1】:

    如果您查看 MvvmCross 源代码 here,您会看到默认行为如何显示 ViewControllers

    您需要通过执行以下操作来更改它: How to change the Push and Pop animations in a navigation based app

    为此,一个想法是拥有一个自定义视图展示器并捕捉到该特定视图模型的导航(覆盖 Show(IMvxTouchView view))

    或者,可能从 UINavigationController 派生,将其设置为 MvvmCross 以使用它(查看 MvxSetup),并在某些事件上更改过渡到该特定视图

    类似这个问题 How to specify view transitions on iPhone

    【讨论】:

    • Andrei,感谢您的帮助,您突出显示了我调查并能够创建有效解决方案的领域。最后,在详细报告之间滚动时,我选择了 TransitionFlipFromRight 和 TransitionFlipFromLeft。请参阅下面的答案。
    【解决方案2】:

    这是我能够按照 Andrei N 的答案中的有用指示提出的解决方案。最后,在详细报告之间滚动时,我选择了 TransitionFlipFromRight 和 TransitionFlipFromLeft。希望它对其他人有用。

    我已经有一个从 MvxModalSupportTouchViewPresenter 继承的演示者类

    public class BedfordViewPresenter : MvxModalSupportTouchViewPresenter
    

    在这个类中,我添加了 MvxPresentationHint 的一个属性。

    private MvxPresentationHint _presentationHint;
    

    在ChangePresentation方法的重写中,上面的属性用来存储传入的参数

        public override void ChangePresentation (MvxPresentationHint hint)
        {
            _presentationHint = hint;
            base.ChangePresentation (hint);
        }
    

    声明了两个新的 MvxPresentationHint 类(见下文)

    在演示者类中,Show 方法被覆盖

        public override void Show(IMvxTouchView view)
        {
            if (_presentationHint is FlipFromRightPresentationHint) {
                var viewController = view as UIViewController;
                MasterNavigationController.PushControllerWithTransition (viewController, UIViewAnimationOptions.TransitionFlipFromRight);
    
            }
            else
                if (_presentationHint is FlipFromLeftPresentationHint)  {
                    var viewController = view as UIViewController;
                    MasterNavigationController.PushControllerWithTransition (viewController, UIViewAnimationOptions.TransitionFlipFromLeft);
                }
                else {
                    base.Show (view);
                }
    
            _presentationHint = null;
        }
    

    使用 PushControllerWithTransition 方法创建了一个为 UINavigationController 提供扩展的新类

    public static class UINavigationControllerExtensions
    {
        public static void PushControllerWithTransition(this UINavigationController 
            target, UIViewController controllerToPush, 
            UIViewAnimationOptions transition)
        {
            UIView.Transition(target.View, 0.75d, transition, delegate() {
                target.PushViewController(controllerToPush, false);
            }, null);
        }
    }
    

    现在需要定义的是两个新的 MvxPresentationHint 类派生。这些属于您的 Core 类库项目,而不是 iOS 应用程序项目。

    public class FlipFromLeftPresentationHint : MvxPresentationHint
    {
        public FlipFromLeftPresentationHint ()
        {
        }
    }
    

    public class FlipFromRightPresentationHint: MvxPresentationHint
    {
        public FlipFromRightPresentationHint ()
        {
        }
    }
    

    我希望这对尝试做类似事情的其他人有所帮助

    【讨论】:

    • 感谢@JDibble 的解释。我正在尝试创建一个从左到右的简单滑动过渡。你知道这是否可以使用 UIViewAnimationOptions 吗?
    【解决方案3】:

    分享我的安卓解决方案:

    正在观看:

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var view = base.OnCreateView(inflater, container, savedInstanceState);
    
            var layout = view.FindViewById<LinearLayout>(Resource.Id.swippeable);
    
            var swipeListener = new SwipeListener(this.Activity);
    
            swipeListener.OnSwipeLeft += (sender, e) => this.ViewModel.LeftCommand?.Execute(); //Here use command into view model
    
            swipeListener.OnSwipeRight += (sender, e) => this.ViewModel.RightCommand?.Execute();
    
            layout.SetOnTouchListener(swipeListener);
    
            return view;
        }
    

    手势监听器:

    public class SwipeListener : SimpleOnGestureListener, View.IOnTouchListener
    {
        private const int SWIPE_THRESHOLD = 100;
        private const int SWIPE_VELOCITY_THRESHOLD = 100;
    
        private readonly GestureDetector gestureDetector;
    
        public SwipeListener(Context ctx)
        {
            this.gestureDetector = new GestureDetector(ctx, this);
        }
    
        public Boolean OnTouch(View v, MotionEvent e)
        {
            return this.gestureDetector.OnTouchEvent(e);
        }
    
        public event EventHandler OnSwipeRight;
    
        public event EventHandler OnSwipeLeft;
    
        public event EventHandler OnSwipeTop;
    
        public event EventHandler OnSwipeBottom;
    
        public override Boolean OnDown(MotionEvent e)
        {
            return true;
        }
    
        public override Boolean OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
        {
            Boolean result = false;
    
            float diffY = e2.GetY() - e1.GetY();
    
            float diffX = e2.GetX() - e1.GetX();
    
            if (Math.Abs(diffX) > Math.Abs(diffY))
            {
                if (Math.Abs(diffX) > SWIPE_THRESHOLD && Math.Abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
                {
                    if (diffX > 0)
                    {
                        SwipeRight();
                    }
                    else
                    {
                        SwipeLeft();
                    }
                    result = true;
                }
            }
            else if (Math.Abs(diffY) > SWIPE_THRESHOLD && Math.Abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
            {
                if (diffY > 0)
                {
                    SwipeBottom();
                }
                else
                {
                    SwipeTop();
                }
                result = true;
            }
    
            return result;
        }
    
        public void SwipeRight()
        {
            this.OnSwipeRight?.Invoke(this, EventArgs.Empty);
        }
    
        public void SwipeLeft()
        {
            this.OnSwipeLeft?.Invoke(this, EventArgs.Empty);
        }
    
        public void SwipeTop()
        {
            this.OnSwipeTop?.Invoke(this, EventArgs.Empty);
        }
    
        public void SwipeBottom()
        {
            this.OnSwipeBottom?.Invoke(this, EventArgs.Empty);
        }
    }
    

    【讨论】:

    • 这行得通,应该被接受为答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 2013-06-04
    相关资源
    最近更新 更多