Iphone SDK - 动画子视图

时间:2009-05-29 16:41:14

标签: iphone animation uiview uiviewcontroller

我的View有一个UIWebView和一个OptionsPane(Custom UIViewController with Custom view)。

我希望在显示视图时,选项窗格(位于主视图顶部)FLIP就位。我正在使用代码,我得到了一个奇怪的结果。

第一次显示视图时,选项窗格似乎已经可见......当我在我的navController上点击BACK,再次拉起View时,动画效果很好。

有人能说清楚这个话题吗?

- (void)viewDidLoad {
    [super viewDidLoad];
    optionsPane=[[OptionsPaneController alloc] initWithNibName:@"OptionsPane" bundle:nil];
}

- (void)viewWillAppear:(BOOL)animated {

    [optionsPane.view removeFromSuperview];
    [self checkOptionsVisible];
}

-(void)checkOptionsVisible{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5]; 
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[optionsPane view] cache:YES];
    [[self view] addSubview:[optionsPane view]];
    [theWebView setFrame:CGRectMake(0,87,320,230)];
    [[optionsPane view] setFrame:CGRectMake(0,0,320,87)];
    [UIView commitAnimations];      
}

4 个答案:

答案 0 :(得分:1)

嗯,我不认为viewWillAppear消息是第一次发送的。我在SDK中读到了两件事。你应该在该消息中打电话给super,并且有一个很大的警告可能适用于你的第一次:

  

警告:如果属于视图控制器的视图直接添加到视图层次结构中,则视图控制器将不会收到此消息。如果向视图层次结构插入或添加视图,并且它具有视图控制器,则应直接向关联的视图控制器发送此消息。未能发送视图控制器此消息将阻止显示任何关联的动画。

最终,我会通过调试器并确保在您认为它时发送了viewWillAppear消息。

答案 1 :(得分:0)

根据您的具体情况更新:

取而代之的是四个观点:

  1. 支持视图

  2. 主视图

  3. 后视图(选项窗格)100像素

  4. 前视图(空白视图)100像素

  5. 正常将主视图添加到支持视图。

    将前视图添加到您希望显示选项窗格的支持视图。

    确保前视图和后视图具有相同的框架。

    使用相同的代码,使用方法翻转前视图和后视图。


    原始答案

    您需要3次观看:

    1. 支持视图

    2. 前视图

    3. 后视图

    4. 背景视图只是握住另外两个来回翻转,下面是翻转方法。我将它们放在backingViewController中:

      - (void)displayBack{
      
          //parent controller is an ivar so the sub-view controllers know who their daddy is
          backController.parentController = self;
      
      
          [UIView beginAnimations:nil context:@"flipTransitionToBack"];
          [UIView setAnimationDuration:1.2];
      
          //note self.view IS the backing view
          [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
      
          //remove the front view
          [[frontController view] removeFromSuperview];
          //add the back view view
          [self.view addSubview:[backController view]];
          [UIView commitAnimations];
      
          //giving a heads up to the view that is about to come on screen
          [backController viewWillAppear:YES];
      
      }
      
      
      
      - (void)displayFront{
      
          [UIView beginAnimations:nil context:@"flipTransitionToFront"];
          [UIView setAnimationDuration:1.2];
      
          [UIView setAnimationDelegate:self];
      
          //I'm interested in knowing this has happened
          [UIView setAnimationDidStopSelector:@selector(flipAnimationDidEndWithID:finished:context:)];
      
          [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
          //remove back view
          [[backController view] removeFromSuperview];
          //add the front view
          [self.view addSubview:[frontController view]];
          [UIView commitAnimations];
      
      }  
      

答案 2 :(得分:0)

如果我理解你的解释,我前几天遇到了一个非常类似的问题。

第一次加载时发生的事情是viewDidLoad首先触发。加载nib文件所需的时间比viewWillAppear触发自身要多一些时间。

我们得到的是在viewWillApper已经退役之后加载nib。

在此之后的任何负载上,viewDidLoad都不会触发,让viewWillAppear执行其忠实的翻转工作。

怎么办?
首先,尝试将代码更改为使用“viewDidAppear”。这应该有所帮助,但你必须看看它是否看起来不错。

另一个选项(丑陋的,我知道)也是在viewDidLoad上调用checkOptionsVisible。
如果没有这方面的帮助,我会将计时器视为黑客 - 如果要求允许的话。

我希望能让你更接近解决问题。

答案 3 :(得分:0)

UIViewController上的view属性是懒惰加载的 - 即使你在这里使用nib初始化时,视图本身实际上也不会在第一次访问属性时实例化。 / p>

如果没有看到更多代码,很难确切知道发生了什么,但是如果你在viewDidLoad中访问optionsPane.view,你可能会得到你想要的结果(你不需要对它做任何事情,只需访问属性来强制加载)。