2012-02-23 16 views
0

私は、製品のリストを入力したUITableViewControllerを持つアプリをやっています。各行は、行内の製品の詳細を表示するUIViewControllerにセグメントします。各行をタップして次の製品の詳細を確認してから、ユーザーにとっては面倒すぎるかもしれませんが、この機能を追加することにしました。ユーザーが製品のUIViewControllerをスワイプすると、UIViewControllerが次の製品が押し出される。ビューコントローラの委任と解任

しかし、今のところ、これを実装する最善の方法はわかりません。私はスワイプが達成されるように、製品の配列をUIViewControllerに渡すように誘惑されますが、これはMVCフレームワークの違反でしょうか?ビューは、提示しているデータを所有することはできません。製品の詳細UIViewControllerは、渡された特定の製品についてのみ知っているべきであり、それ以外のものは知っていないはずです。

これは委任を使用して達成できると思いますが、どうすればよいかわかりません。誰か助けてくれますか?ありがとう!

編集: Rob Mayoffのコードは本当に役に立ち、私はそれを実装することにしました。しかしその間、スワイプを実装する代わりに、単純な丸い四角形のボタンを使用して関数を呼び出すだけです。

- (IBAction)showNextProduct:(id)sender { 
    [self.productsTVC goToProductAtIndex:self.productIndex + 1]; 
} 

- (IBAction)showPriorProduct:(id)sender { 
    [self.productsTVC goToProductAtIndex:self.productIndex - 1]; 
} 

しかし、私はメッセージで、私のアプリのクラッシュをボタンのいずれかをクリックするたび:Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted. Unbalanced calls to begin/end appearance transitions for <ProductDetailsViewController: 0x6e510c0>.

答えて

3

のは、あなたがあるCatalogViewControllerUITableViewControllerのサブクラスである)とProductViewControllerを(持っているとしましょうUIViewControllerのサブクラス)。

スワイプを次の製品に実装する最も簡単な方法は、ProductViewControllerCatalogViewControllerへの参照を与えることです。 weak(ARCを使用する場合)またはassign(ARCを使用しない場合)。また、カタログ内の製品のインデックスを保持しているプロパティをお勧めします:

@interface ProductViewController 

@property (nonatomic, weak) CatalogViewController *catalogViewController; 
@property (nonatomic) NSInteger productIndex; 

@end 

その後スワイプのためのアクションメソッドでは、あなたがCatalogViewControllerにメッセージを送信する次の(または前に行くためにそれを求めてカタログの)製品:CatalogViewController

@implementation ProductViewController 

- (IBAction)showNextProduct:(id)sender { 
    [self.catalogViewController goToProductAtIndex:self.productIndex + 1]; 
} 

- (IBAction)showPriorProduct:(id)sender { 
    [self.catalogViewController goToProductAtIndex:self.productIndex - 1]; 
} 

、あなたがProductViewControllerを作成するたび、あなたはこれらのプロパティを設定する必要があります。

@implementation CatalogViewController 

- (ProductViewController *)productViewControllerForProductAtIndex:(NSInteger)index { 
    if (index < 0 || index >= self.products.count) 
     return nil; 
    ProductViewController *vc = [[ProductViewController alloc] initWithProduct:[self.products objectAtIndex:index]]; 
    vc.catalogViewController = self; 
    vc.productIndex = index; 
    return vc; 
} 

そしてあなたのようgoToProductAtIndex:メソッドを実装します。あなたはより多くのソフトウェア・engineeryを取得したい場合は、あなたが作成することができます

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    [self goToProductAtIndex:indexPath.row]; 
} 

- (void)goToProductAtIndex:(NSInteger)index { 
    ProductViewController *vc = [self productViewControllerForProductAtIndex:index]; 
    if (!vc) 
     return; 
    NSMutableArray *vcs = [[self.navigationController viewControllers] mutableCopy]; 
    while (vcs.lastObject != self) 
     [vcs removeLastObject]; 
    [vcs addObject:vc]; 
    [self.navigationController setViewControllers:vcs animated:YES]; 
} 

あなたは、テーブルの行選択を処理するために、同じ方法を使用することができますgoToProductAtIndex:メソッドの周りのプロトコルを使用し、ProductViewControllerCatalogViewControllerクラスについて知ることを避けるためにそれを使用してください。

+0

ありがとう@rob。私はこの解決策を試してみると、私はあなたに知らせるでしょう。ありがとう! – acecapades

+0

rob、「予期しない状態でナビゲーション遷移を終了しました。ナビゲーションバーのサブビューツリーが壊れている可能性があります。" acecapades

+0

'viewWillAppear:'、 'viewDidAppear:'、 'viewWillDisappear:'、 'viewDidDisappear:'メソッドが 'super'メソッド –