4

我有一个具有 UIWebView 和 OptionsPane 的视图(带有自定义视图的自定义 UIViewController)。

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

第一次显示视图时,选项窗格似乎已经可见...当我在导航控制器上按 BACK 并再次拉起视图时,动画效果完美。

任何人都可以对这个话题有所了解吗?

- (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

4 回答 4

1

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

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

最终,我将运行调试器并确保 viewWillAppear 消息在您认为发送时发送。

于 2009-05-29T17:02:19.450 回答
0

根据您的情况更新:

而是有四个视图:

  1. 支持视图

  2. 主视图

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

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

像往常一样将主视图添加到后备视图。

将前视图添加到您希望选项窗格出现的后视图。

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

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


原始答案

您需要 3 个视图:

  1. 支持视图

  2. 前视图

  3. 后视图

后备视图只保留其他 2 个,因为它们来回翻转以下是翻转方法。我将它们都放在 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];

}  
于 2009-06-02T22:17:45.750 回答
0

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

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

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

在那之后的任何负载上,viewDidLoad 都不会触发,让 viewWillAppear 完成它忠实的翻转工作。

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

另一种选择(丑陋的,我知道)是也调用 viewDidLoad 上的 checkOptionsVisible 。
如果没有这种帮助,我会考虑将计时器视为一种技巧——如果要求允许的话。

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

于 2009-06-03T19:14:36.533 回答
0

UIViewController 上的视图属性是延迟加载的——即使您在这里使用 nib 进行初始化,直到第一次访问该属性时,视图本身才真正被实例化。

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

于 2009-06-03T20:08:03.167 回答