UIViewAnimation 由属于 UINavigationController 的 UIViewController 完成?

Posted

技术标签:

【中文标题】UIViewAnimation 由属于 UINavigationController 的 UIViewController 完成?【英文标题】:UIViewAnimation done by a UIViewController belonging to a UINavigationController? 【发布时间】:2010-04-10 13:36:45 【问题描述】:

我有一个用户导航的 UINavigationController。 将特定的 UIViewController 推送到导航堆栈时,导航栏中会出现一个“设置”按钮。当用户单击此按钮时,我想将当前视图/控制器(即屏幕上的所有内容,包括导航栏)翻转到设置视图。

所以我有一个 SettingsViewController,我想从我的 CurrentViewController 翻转到它,它位于 navigationController 堆栈上。

尝试执行此操作时,我遇到了各种奇怪的行为,属于 SettingsViewController 的 UIView 将开始动画,滑动到位,导航按钮四处移动,没有我想的那样。

-(void)settingsHandler 

    SettingViewController *settingsView = [[SettingViewController alloc] init];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
                           forView:self.navigationController.view
                            cache:YES];

    [self.navigationController.view addSubview:settingsView.view];

    [UIView commitAnimations];


上面的结果是视图正确翻转,但是 SettingsViewController 的子视图都定位在 (0, 0) 并且在转换之后,它们“卡入”到位?

是不是因为我在viewDidLoad中实例化并添加了我的子视图,像这样?

- (void)viewDidLoad 

    UIImageView *imageBg = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 460.0f)];
    [imageBg setImage:[UIImage imageNamed:@"background.png"]];
    [self.view addSubview:imageBg];
    [imageBg release];

    SettingsSubview *switchView = [[SettingsSubview alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 460.0f)];
    [self.view addSubview:switchView];
    [switchView release];
    [super viewDidLoad];

1:我应该如何正确地进行“翻转”转换,从 UINavigationController 中的 UIViewController 到新的 UIViewController,然后从新的 UIViewController 再回到驻留在 UINavigationControllers 堆栈上的“原始”UIViewController ?

2:在将子视图实例化并添加到 UIViewController 时,我是否应该使用与“viewDidLoad”方法不同的方法?

-问题 2 更像是“最佳实践”。我见过不同的方式 这样做,我在查找或理解生命周期文档以及有关该主题的不同线程和帖子时遇到了麻烦。我缺少“最佳实践”示例。

非常感谢您提供的任何帮助:)

【问题讨论】:

【参考方案1】:

如果您想以编程方式创建视图层次结构,则可以在 -loadView 中进行。为此,您必须自己创建视图,添加其所有子视图,然后将其分配给视图属性,如下所示:

- (void)loadView 
    UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 460.0f)];

    UIImageView *imageBg = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 460.0f)];
    [imageBg setImage:[UIImage imageNamed:@"background.png"]];
    [containerView addSubview:imageBg];
    [imageBg release];

    SettingsSubview *switchView = [[SettingsSubview alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 460.0f)];
    [containerView addSubview:switchView];
    [switchView release];

    self.view = containerView;
    [containerView release];

这有助于了解调用此方法的上下文以及默认情况下它的行为方式。第一次访问 UIViewController 的 view 属性时,默认的 getter 方法会调用 -loadView 来延迟加载视图。 -loadView 的默认实现从 nib 加载视图(如果指定了)。否则,它会创建一个普通的 UIView 对象并将其设置为控制器的视图。通过重写此方法,您可以确保视图的层次结构在第一次访问时完全形成。

-viewDidLoad 应该用于在视图层次结构完全加载后需要进行的任何后续设置。无论视图是从 nib 加载还是在 loadView 中以编程方式构建,都会调用此方法。

【讨论】:

谢谢 cduhn。这是一个很好的解释和完美的例子。

以上是关于UIViewAnimation 由属于 UINavigationController 的 UIViewController 完成?的主要内容,如果未能解决你的问题,请参考以下文章

UIViewAnimation 立即播放,延迟被忽略

UiViewAnimation 不调用 setAnimationDidStopSelector

在 iOS 中导航期间更改 UITabBar

AVPlayer replaceCurrentItemWithPlayerItem 打破 UIViewAnimation

从枚举类型 'enum UIViewAnimationOption 到不同枚举类型 uiviewanimation 的隐式转换

UIViewAnimation 导致从枚举类型隐式转换