0

私のルートコントローラーは、静的セルとナビゲーションコントローラーを備えたTableViewControllerです。選択したセルに応じて、構成を適宜変更する別のViewController(TableViewが埋め込まれている)をプッシュします(ボタンが有効かどうか、dbテーブルまたはNSArrayからのセルデータなど)。いくつかの「コントローラーA」セルを選択すると、「コントローラーB」または「コントローラーC」が呼び出され、いくつかのデータが渡されます。

私が試しているコードは次のようになります。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
   switch (indexPath.row) {
        case 0:
        {
            [self performSegueWithIdentifier:@"segueToType" sender:self];
        }
            break;
        case 1:
        {
            [self performSegueWithIdentifier:@"segueToType" sender:self];
        }
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

if ([[segue identifier] isEqualToString:@"segueToType"])
{
    NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
    NSInteger rowNumber = selectedIndexPath.row;
    switch (rowNumber) {
        case 0:
        {
            TypeSelectController *selCon = [segue destinationViewController];
            selCon.myPet = self.myPet;
            selCon.sel = @"tipo";
            selCon.delegate = self;
        }
            break;
        case 1:
        {
            TypeSelectController *selCon = [segue destinationViewController];
            selCon.myPet = self.myPet;
            selCon.sel = @"razza";
            selCon.delegate = self;
        }
            break;
        default:
            break;
    }

} 
}

この場合、たとえば、「コントローラーB」のみを呼び出していますが、「コントローラーA」の選択したセルに応じて、さまざまな方法で構成されます(「selCon.sel」文字列によって異なります)。

「コントローラーB」には、次のようなコードがあります。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([sel isEqualToString:@"tipo"]) {
    NSString *itemToPassBack = [tipi objectAtIndex:indexPath.row];
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack ofType:@"tipo"];
    [self.navigationController popViewControllerAnimated:YES];
} else if ([sel isEqualToString:@"razza"]) {
    NSString *itemToPassBack = [razze objectAtIndex:indexPath.row];
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack ofType:@"razza"];
    [self.navigationController popViewControllerAnimated:YES];
}
}

繰り返しになりますが、文字列「sel」の値に応じて、「コントローラーA」に異なるデータを返します。

コントローラAの最初のセルを選択すると、コントローラBのシーンが正しく取得されます。次に、セルを選択し、正しいデータを使用してコントローラーAに戻ります。ここで、コントローラーAの2番目のセルを選択し、コントローラーBのセルを選択しようとすると、ナビゲーションが希望どおりに応答せず、コントローラーCのシーンが表示され、次にコントローラーAと次のエラーが発生します。

ネストされたプッシュアニメーションにより、ナビゲーションバーが破損する可能性があります

予期しない状態でナビゲーション遷移を終了します。ナビゲーションバーのサブビューツリーが破損する可能性があります。

の外観遷移を開始/終了するための不均衡な呼び出し。

私は何が間違っているのですか?

4

2 に答える 2

0

ストーリーボードの例でプロトコルとデリゲートを使用する簡単な例。あなたはすでにほとんどの道を進んでいるので、ここでハイライトを打つだけです。

コントローラa(親)には、categoryというNSStringプロパティとpartNumberというNSStringプロパティがあります。テーブルビューがあります。セグエを開始するために選択された行。[自己performSegueWithIdentifier:@ "segueToType" sender:self];

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

if([[セグエ識別子] isEqualToString:@ "segueToType"]){
ControllerB * b = segue.destinationViewController; b.category = self.category; b.delegate = self; }

コントローラーBを表示

@protocol-(void)doSomethingWithPickedPartNumber:(NSString *)partNumber; @終わり

//渡されたカテゴリの部品番号を使用してテーブルビューを設定します。

//行が選択されているので、送り返したいpartNumberがあります。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *pn = [self.listOfParts objectAtIndex:indexPath.row];

 //options - set the variable in the parent or call a method in the parent
 self.delegate.partNumber = pn;
 //if you set the variable in the parent - you can check for it in the -(void)viewWillAppear  method and reconfigure the parent view if needed

 //or do this
 [self.delegate doSomethingWithPickedPartNumber:pn];

 //this is actually calling a method in the parent.  remember you don't have a view you can see yet, but its in memory and you can modify things so when the child pops back it will look how you want it.  Also note, you can name the protocol methods what ever you want, as long as they match up from the parent  to the protocol in the child.


 //then return to parent
 [self.navigationController popViewControllerAnimated:YES];

}

于 2012-08-05T17:55:39.943 に答える
0

わかりました、これをもう一度試してください。

  • 髪の色の例を使用してみましょう。コントローラaにテーブルがあり、髪の色の静的セルがあります。選択した色のテキスト値を表示するとします。cell.textLabel=self.hairColor。空白の場合、ユーザーはセルに触れて新しいコントローラーを開いて色を選択できます。

セグエした新しいViewControllerで、「hairColor」を検索するように指示するプロパティを設定します。したがって、listOfHairChoicesという名前のデータベースからリストを作成します。

ユーザーが3行目を選択するので、このようにデリゲート参照を使用して親にプロパティを設定します。self.delegate.hairColor = [self.listOfHairChoices objectAtIndex:indexPath.row]; 次に、子vcをポップして閉じ、親にポップバックします。[self.navigationController popViewCon..etc]

次に、親に戻り、-(void)viewDidAppearで、次のようにテーブルビューをリロードします。[self.tableView reloadData]

これで、元のテーブルビューに、子ビューコントローラで選択されたセルの値が表示されます。

これは簡単な方法であり、各ステップで、使用しているプロパティと設定する必要のあるプロパティを決定するロジックが必要ですが、既存のフレームワークで機能します。

別のアプローチは、提示しているデータのモデルクラスを作成し、モデルを子VCに渡すことです。モデルを更新して戻し、各遷移後に更新されたモデルからテーブルをリロードするだけです。そのアプローチに慣れていないかもしれませんが、それは物事を単純化し、テーブルビューの各行に対して現在持っているすべての条件付きロジックを減らします。

hope this suggestion helps you with your project.

于 2012-08-05T18:28:12.943 に答える