同一屏幕上的子视图控制器之间的 IOS 转换

Posted

技术标签:

【中文标题】同一屏幕上的子视图控制器之间的 IOS 转换【英文标题】:IOS Transition between child viewControllers on same screen 【发布时间】:2012-04-26 00:09:38 【问题描述】:

我正在尝试让新的 ios 5 Container viewControllers 正常工作,但我在它们之间设置动画时遇到了问题。

我有一个“rootViewController”。在这个控制器中,我添加了 2 个子视图控制器。这个功能几乎就像一个 splitViewController。在左边我有一个处理导航的 VC,在右边我有一个显示特定内容的 VC。

我正在尝试在右侧的 VC 和将替换它的新 VC 之间设置动画。

这是我的动画代码:

public void Animate(UIViewController toController) 
    AddChildViewController(toController);
    activeRightController.WillMoveToParentViewController(null);
    toController.View.Frame = activeRightController.View.Frame;
    Transition(activeRightController, toController, 1.0, UIViewAnimationOptions.TransitionCurlUp, () => ,
        (finished) => 
        activeRightController.RemoveFromParentViewController();
        toController.DidMoveToParentViewController(this);
        activeRightController = toController;
    );
    activeRightController = toController;

几乎一切正常,它使用 CurlUp 过渡过渡到我的新视图,但是过渡本身会跨越整个屏幕......而不仅仅是我想要过渡的单个视图。它“卷曲”父视图,而不是子视图。然而,它确实只替换了它下面的子视图。我希望这是有道理的。

【问题讨论】:

【参考方案1】:

我创建了一个新的 UIViewController 类,它是右侧控制器的瘦容器并处理交换动画。请参阅下面的示例。

using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Drawing;

namespace delete20120425

    [Register ("AppDelegate")]
    public partial class AppDelegate : UIApplicationDelegate
    
        UIWindow window;
        MainViewController mvc;

        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        
            window = new UIWindow (UIScreen.MainScreen.Bounds);

            mvc = new MainViewController ();

            window.RootViewController = mvc;
            window.MakeKeyAndVisible ();

            return true;
        
    

    public class MainViewController : UIViewController
    
        SubViewController vc1;
        ContainerViewController vc2;

        public override void ViewDidLoad ()
        
            base.ViewDidLoad ();

            vc1 = new SubViewController (UIColor.Blue);
            this.AddChildViewController (vc1);
            this.View.AddSubview (vc1.View);

            UIButton btn = UIButton.FromType (UIButtonType.RoundedRect);
            btn.Frame = new RectangleF (20, 20, 80, 25);
            btn.SetTitle ("Click", UIControlState.Normal);
            vc1.View.AddSubview (btn);

            SubViewController tmpvc = new SubViewController (UIColor.Yellow);
            vc2 = new ContainerViewController (tmpvc);

            this.AddChildViewController (vc2);
            this.View.AddSubview (vc2.View);

            btn.TouchUpInside += HandleBtnTouchUpInside;
        

        void HandleBtnTouchUpInside (object sender, EventArgs e)
        
            SubViewController toController = new SubViewController (UIColor.Green);
            vc2.SwapViewController (toController);
        

        public override void ViewWillLayoutSubviews ()
        
            base.ViewDidLayoutSubviews ();

            RectangleF lRect = this.View.Bounds;
            RectangleF rRect = lRect;

            lRect.X = lRect.Y = lRect.Y = 0;

            lRect.Width = .3f * lRect.Width;
            rRect.X = lRect.Width + 1;
            rRect.Width = (.7f * rRect.Width)-1;

            this.View.Subviews[0].Frame = lRect;
            this.View.Subviews[1].Frame = rRect;
        

        public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
        
            return true;
        
    

    public class ContainerViewController : UIViewController
    
        UIViewController _ctrl; 
        public ContainerViewController (UIViewController ctrl)
        
            _ctrl = ctrl;   
        

        public override void ViewDidLoad ()
        
            base.ViewDidLoad ();

            AddChildViewController (_ctrl);
            View.AddSubview (_ctrl.View);
        

        public void SwapViewController (UIViewController toController)
        
            UIViewController activeRightController = _ctrl;

            AddChildViewController(toController);
            activeRightController.WillMoveToParentViewController(null);
            toController.View.Frame = activeRightController.View.Frame;
            Transition(activeRightController, toController, 1.0, UIViewAnimationOptions.TransitionCurlUp, () => ,
                (finished) => 
                activeRightController.RemoveFromParentViewController();
                toController.DidMoveToParentViewController(this);
                activeRightController = toController;
            );
            activeRightController = toController;   
        

        public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
        
            return true;
        

        public override void ViewWillLayoutSubviews ()
        
            base.ViewWillLayoutSubviews ();
            RectangleF tmp = this.View.Frame;
            tmp.X = tmp.Y = 0;
            _ctrl.View.Frame = tmp;
        
     

    public class SubViewController : UIViewController
    
        UIColor _back;
        public SubViewController (UIColor back)
        
            _back = back;
        

        public override void ViewDidLoad ()
        
            base.ViewDidLoad ();
            this.View.BackgroundColor = _back;
        

        public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
        
            return true;
        
    

【讨论】:

在这个例子之前我不太了解 Container Vew 控制器。非常感谢。这非常有效。 你将如何返回上一个视图?

以上是关于同一屏幕上的子视图控制器之间的 IOS 转换的主要内容,如果未能解决你的问题,请参考以下文章

(iOS) 音频播放器作为应用程序中所有父视图控制器上的子视图控制器

如何在 iOS 中滑动 UIViewController 中包含的子视图控制器?

当一个新的视图控制器被推送到导航控制器时,将一个子视图保持在屏幕上的同一位置?

如何在 iOS 上的视图之间切换

iOS - 创建自定义过渡动画

如何在导航视图控制器上滑动时进行即时转换