1

ユーザーがナビゲートするUINavigationControllerがあります。特定のUIViewControllerをナビゲーションスタックにプッシュすると、ナビゲーションバーに「設定」ボタンが表示されます。ユーザーがこのボタンをクリックしたときに、現在のビュー/コントローラー、つまりナビゲーションバーを含む画面上のすべてのものを設定ビューに切り替えたいと思います。

したがって、navigationControllerスタックにあるCurrentViewControllerからフリップしたいSettingsViewControllerがあります。

これを行おうとすると、あらゆる種類の奇妙な動作が発生します。SettingsViewControllerに属するUIViewがアニメーションを開始し、所定の位置にスライドし、navigationButtonが動き回り、私が思うように何も動作しません。

-(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は、より「ベストプラクティス」です。私はそれを行うさまざまな方法を見てきましたが、ライフサイクルドキュメントと、このテーマに関するさまざまなスレッドや投稿を見つけたり理解したりするのに苦労しています。「ベストプラクティス」の例がありません。

助けてくれてありがとう:)

4

1 に答える 1

3

ビュー階層をプログラムで作成する場合、それを行う場所は -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 のビュー プロパティに初めてアクセスすると、デフォルトの getter メソッドが -loadView を呼び出してビューを遅延ロードします。-loadView のデフォルトの実装は、指定されている場合、nib からビューをロードします。それ以外の場合は、プレーンな UIView オブジェクトを作成し、それをコントローラーのビューとして設定します。このメソッドをオーバーライドすることで、最初にアクセスしたときにビューの階層が完全に形成されるようにすることができます。

-viewDidLoad は、ビュー階層が完全にロードされた後に発生する必要がある後続のセットアップに使用する必要があります。このメソッドは、ビューが nib からロードされているか、loadView でプログラムによって構築されているかに関係なく呼び出されます。

于 2010-04-10T20:40:40.837 に答える