委派和解雇视图控制器

时间:2012-02-23 01:46:24

标签: iphone objective-c xcode

我正在做一个有一个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>.

1 个答案:

答案 0 :(得分:3)

假设您有CatalogViewControllerUITableViewController的子类)和ProductViewControllerUIViewController的子类)。

实施“刷到下一个产品”的最简单方法是为ProductViewController提供CatalogViewController的引用。它应该是weak(如果使用ARC)或assign(如果不使用ARC)。您还需要一个包含目录中产品索引的属性:

@interface ProductViewController

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

@end

然后在滑动的操作方法中,您向CatalogViewController发送消息,要求它转到目录中的下一个(或之前的)产品:

@implementation ProductViewController

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

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

CatalogViewController中,无论何时创建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:方法,如下所示:

- (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];
}

您可以使用相同的方法处理表格行选择:

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

如果您想获得更多软件工具,可以围绕goToProductAtIndex:方法创建协议,并使用该方法避免让ProductViewController了解CatalogViewController类。