UIViewAnimation是否由属于UINavigationController的UIViewController完成?

UIViewAnimation是否由属于UINavigationController的UIViewController完成?,uiview,uiviewcontroller,uianimation,Uiview,Uiviewcontroller,Uianimation,我有一个用户导航的UINavigationController。 将特定UIViewController推到导航堆栈上时,导航栏中会出现一个“设置”按钮。当用户单击此按钮时,我希望将当前视图/控制器(即屏幕上的所有内容,包括导航栏)翻转到设置视图 因此,我有一个SettingsViewController,我想从位于navigationController堆栈上的CurrentViewController中切换到它 我尝试这样做时会出现各种奇怪的行为,属于SettingsViewControll

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

因此,我有一个SettingsViewController,我想从位于navigationController堆栈上的CurrentViewController中切换到它

我尝试这样做时会出现各种奇怪的行为,属于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?

- (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];
}
2:在实例化子视图并将其添加到UIViewController时,我是否应该使用与“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];
}
-问题2更多的是一个“最佳实践”问题。我看到了不同的方式 我很难找到或理解生命周期文档以及关于这个主题的不同线程和帖子。我错过了“最佳实践”的例子


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

如果您想以编程方式创建视图层次结构,可以在-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以延迟加载该视图。如果指定了nib,则-loadView的默认实现将从nib加载视图。否则,它将创建一个普通UIView对象并将其设置为控制器的视图。通过重写此方法,可以确保视图的层次结构在首次访问时完全形成


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

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