18

3 つのビュー コントローラーを持つ単純なアプリケーションを作成しています。ルート ビュー コントローラーはitem listing、基本的なテーブル ビューです。このビュー コントローラーから、ユーザー インタラクションに基づいて 2 つの異なるビュー コントローラーcreate item(ビュー コントローラーまたはビュー コントローラー) をプッシュしview itemます。

つまり、ストーリーボードのセグエは V か何かのように見えます。

私のcreate itemView Controllerでは、ユーザーが新しいアイテムを作成したときにルートView Controllerにポップバックしたいのですが、次にview itemコントローラーにプッシュして、新しく作成したアイテムを見ることができるようにします。

私はこれを機能させることができないようです。ルート ビュー コントローラーに戻るのは簡単ですが、そのview itemコントローラーをプッシュすることはできません。

何か案は?以下にコードを貼り付けました。ポップ機能は機能しますが、新しいビューは表示されません。

- (void) onSave:(id)sender {

    CLLocation *currentLocation = [[LocationHelper sharedInstance] currentLocation];

    // format the thread object dictionary
    NSArray* location = @[ @(currentLocation.coordinate.latitude), @(currentLocation.coordinate.longitude) ];
    NSDictionary* thread = @{ @"title": _titleField.text, @"text": _textField.text, @"author": @"mustached-bear", @"location": location };

    // send the new thread to the api server
    [[DerpHipsterAPIClient sharedClient] postPath:@"/api/thread"
                                       parameters:thread
                                          success:^(AFHTTPRequestOperation *operation, id responseObject) {

                                              // init thread object
                                              Thread *thread = [[Thread alloc] initWithDictionary:responseObject];

                                              // init view thread controller
                                              ThreadViewController *viewThreadController = [[ThreadViewController alloc] init];
                                              viewThreadController.thread = thread;

                                              [self.navigationController popToRootViewControllerAnimated:NO];
                                              [self.navigationController pushViewController:viewThreadController animated:YES];

                                          }
                                          failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                                              [self.navigationController popToRootViewControllerAnimated:YES];

                                          }];

}
4

8 に答える 8

44

私があなたを正しく理解していれば、View Controller のスタックがあります。

A (root) - B - C - D - E

そして、あなたはそれを次のようにしたい:

A (root) - F

右?その場合:

NSArray *viewControllers = self.navigationController.viewControllers;
NSMutableArray *newViewControllers = [NSMutableArray array];

// preserve the root view controller
[newViewControllers addObject:[viewControllers objectAtIndex:0]];
// add the new view controller
[newViewControllers addObject:viewThreadController];
// animatedly change the navigation stack
[self.navigationController setViewControllers:newViewControllers animated:YES];

スイフト4

// get current view controllers in stack and replace them
let viewControllers = self.navigationController!.viewControllers
let newViewControllers = NSMutableArray()

// preserve the root view controller
newViewControllers.add(viewControllers[0])
// add the new view controller
newViewControllers.add(viewThreadController)
// animatedly change the navigation stack
self.navigationController?.setViewControllers(newViewControllers as! [UIViewController], animated: true)
于 2012-08-06T00:17:44.827 に答える
8


[self.navigationController pushViewController:viewThreadController animated:YES]; その前のステートメントとは異なる NavigationController を使用していると思います。ルートビューコントローラーにポップした後、現在のナビゲーションコントローラーが失われるためです。代わりにこのコードを使用して解決してください

UINavigationController *nav = self.navigationController; 
[self.navigationController popToRootViewControllerAnimated:NO];
[nav pushViewController:viewThreadController animated:YES];

また、これで問題全体が解決するとは思いません。おそらく、2 つの高速な pop と push によって NavigationController が無効になる可能性があるというエラーが表示されます。
そして、それを解決するには、2番目のView ControllerのviewDidDissappearメソッドでNavigationControllerをプッシュするか、メインView Controller(アイテムリスト)のviewDidAppearメソッドでプッシュします。

于 2012-08-06T00:05:48.347 に答える
6

目的を達成する簡単な方法は、いくつかの単純なロジックをメイン ルート ビュー コントローラーの -(void)viewWillAppear メソッドに組み込み、デリゲート コールバックを使用してロジック スイッチを切り替えることです。基本的に、ルート コントローラへの「後方参照」です。ここに簡単な例があります。

メイン ルート コントローラー (このコントローラー a と考えてください) - コントローラー A と呼びます。ジャンプ ステータスを追跡するプロパティを設定します。

@property (nonatomic) BOOL jumpNeeded;

いくつかのロジックをセットアップする

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.jumpNeeded ? NSLog(@"jump needed") : NSLog(@"no jump needed");

    if (self.jumpNeeded) {
        NSLog(@"jumping");
        self.jumpNeeded = NO;
        [self performSegueWithIdentifier:@"controllerC" sender:self];
    }   
}

ここで、メインのルートコントローラーで、テーブルビューの行が選択されているときに、tableView でコントローラー B にプッシュするときに次のようなことを行います。

[self performSegueWithIdentifer@"controllerB" sender:self];

次に、セグエメソッドの準備を実装します

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

  //setup controller B
  if([segue.identifier isEqualTo:@"controllerB"]){
    ControllerB *b = segue.destinationViewController;
    b.delegate = self;  //note this is the back reference
  }

  //implement controller c here if needed
}

次に、controllerB に移動します。後方参照を保持するために「delegate」というプロパティを設定する必要があり、ルート コントローラーからヘッダー ファイルをインポートする必要があります。

#import "controllerA"

@property (nonatomic,weak) controllerA *delegate;

次に、コントローラーAに戻る直前に、フラグを設定します

   self.delegate.jumpNeeded = YES;
    [self.navigationController popViewControllerAnimated:YES];

それはそれについてです。controllerC で何もする必要はありません。他にもいくつかの方法がありますが、これはニーズに合わせて非常に簡単です。それがうまくいくことを願っています。

于 2012-08-06T01:19:03.213 に答える
5

アプリケーションで使用する Dave DeLong の回答に基づいて UINavigationController でカテゴリを共有し、必要に応じて [戻る] ボタンを常に機能させます。

@implementation UINavigationController (PushNewAndClearNavigationStackToParent)

- (void) pushNewControllerAndClearStackToParent:(UIViewController*)newCont animated:(BOOL)animated
{
    NSArray *viewControllers = self.viewControllers;
    NSMutableArray *newViewControllers = [NSMutableArray array];
    
    // preserve the root view controller
    [newViewControllers addObject:[viewControllers firstObject]];
    // add the new view controller
    [newViewControllers addObject:newCont];
    // animatedly change the navigation stack
    [self setViewControllers:newViewControllers animated:animated];
}

@end
于 2014-09-10T17:08:34.533 に答える
0

ポップバックするとすべての割り当てが解除されるため、これは不可能だと思います。

より良い方法は、データをモデル シングルトン クラスに配置し、rootviewcontroller にポップして、ポップが終了するのをリッスンすることだと思います。次に、モデルにデータが保存されているかどうかを確認して、新しいビューコントローラーをプッシュする必要があるかどうかを確認します。

于 2012-08-05T23:40:36.557 に答える