Делегирование и увольнение контролера представления - PullRequest
0 голосов
/ 23 февраля 2012

Я делаю приложение, в котором UITableViewController заполнен списком продуктов.Каждая строка переходит к UIViewController, который представляет детали продукта в строке.Теперь, поскольку нажатие на каждую строку и возврат к деталям следующего продукта может быть слишком утомительным для пользователя, мы решили добавить эту функцию: когда пользователь проводит UIViewController продукта, UIViewController с подробной информацией дляследующий продукт продвигается.

Но на данный момент я не уверен в лучшем способе реализовать это.Я испытываю желание передать массив продуктов в UIViewController так, чтобы свайп был достигнут, но это будет нарушением инфраструктуры MVC, верно?Представления не могут владеть данными, которые они представляют.Сведения о продукте UIViewController должен знать только о конкретном продукте, который ему передается, а не об остальных, верно?

Я думаю, что это можно сделать с помощью делегирования, но я не уверен, как это сделать.Кто-нибудь может мне помочь?Спасибо!

РЕДАКТИРОВАТЬ: код Роба Мейоффа был действительно полезным, поэтому я решил реализовать его.Но пока, вместо того, чтобы осуществлять пролистывание, я просто использую простую круглую прямоугольную кнопку для вызова функций.

- (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 Ответ

3 голосов
/ 23 февраля 2012

Допустим, у вас есть CatalogViewController (который является подклассом UITableViewController) и ProductViewController (который является подклассом UIViewController).

Самый простой способ реализовать «пролистывание до следующего продукта» - дать 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...