Как установить parentViewController в UIViewController?

Свойство parentViewController для UIViewController выполняется только для чтения, но я устанавливаю пользовательские контроллеры представлений и хотел бы использовать это свойство.

Однако, поскольку он доступен только для чтения, и я не нашел другого способа установить это свойство, мой вопрос: как его установить?

Очевидно, что UINavigationController может каким-то образом установить свойство в -pushViewController, и поэтому может -представитьModalViewController, поэтому он должен быть возможным.

Мне известно, что я могу просто добавить собственное свойство UIViewController, но я уверен, что parentViewController является, в принципе, правильным свойством.

Ответ 1

Однако, поскольку он доступен только для чтения, и я не нашел другого способа установить это свойство, мой вопрос: как его установить?

Если это readonly, вы не можете использовать точечную нотацию без получения ошибки компилятора.

Однако вы можете использовать categories, чтобы добавить собственный modifyParentViewController метод в класс UIViewController.

Даже если свойство только для чтения, сама переменная может быть модифицируемой, если она не @protected. Если это @protected, подклассификация контроллера вида может позволить вам изменить эту переменную.

Ответ 2

Решение:

   - (void)setParentController:(UIViewController*)parent{
 [self setValue:parent forKey:@"_parentViewController"];
    }

Это не вызывает проблем с компоновщиком!

PS: Не используйте "setParentViewController" в качестве имени метода, поскольку этот метод существует в частном API, и Apple говорит: "Непубличным API, который включен в ваше приложение, является setParentViewController:.

Если вы определили метод в своем исходном коде с тем же именем, что и вышеупомянутый API, мы предлагаем изменить имя метода, чтобы оно больше не сталкивалось с частным API Apple, чтобы ваше приложение не помещалось в будущие представления.

Пожалуйста, разрешите эту проблему в следующем обновлении... "

Ответ 3

Я понимаю, что этот вопрос задавался до iOS 5, но для справки вы должны использовать addChildViewController, когда хотите вложить UIViewControllers. Это также автоматически установит свойство parentViewController.

- (void)addChildViewController:(UIViewController *)childController NS_AVAILABLE_IOS(5_0);

Подробнее о "Создание пользовательских контроллеров содержимого" можно узнать в Apple.

Ответ 4

Я попробовал купить предложение Alex для категории UIViewController, и он работал в симуляторе, но не на моем телефоне. вот категория

@interface UIViewController (parentSetter) 
-(void)setParentUIViewController:(UIViewController*)parent;
@end

@implementation UIViewController (parentSetter)
-(void)setParentUIViewController:(UIViewController*)parent
{
 _parentViewController = parent;
}
@end

Он компилируется и работает отлично, но обратите внимание на элемент подчеркивания, который немного не работает. Это вызывает ошибку компоновщика при компиляции с 3.0 SDK.

У меня есть контейнер, который имеет 2 подзаголовка, и одна из них - таблица. Таблице нужен родитель, чтобы он мог взаимодействовать с панелью навигации, между прочим.

Я пойду с этим решением:

@interface AdoptedTableViewController : UITableViewController {
    UIViewController* surrogateParent;
}

-(UINavigationController*)navigationController;
@property (nonatomic, assign) IBOutlet UIViewController *surrogateParent;
@end

@implementation AdoptedTableViewController
@synthesize surrogateParent;

-(UINavigationController*)navigationController
{
    if( [super navigationController] )//self.navigationController ) 
    {
        return [super navigationController];
    }
    else
    {
        return surrogateParent.navigationController;
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Теперь все мои контроллеры просмотра таблиц принятыTableViewControllers. Основная причина, по которой они нуждаются в родителях, заключается в том, что они могут подключать контроллеры представлений к стеку навигации, поэтому прозрачно обрабатывается получателем навигационного контроллера.

Было бы неплохо, если parentViewController не был только для чтения, но в моем dabble с _parentViewController я обнаружил, что иерархия ViewController больше, чем просто это свойство. Я думаю, что в этих отношениях может быть много связей и обязанностей, которые Apple недостаточно очистила для масс. Например, я заметил странное поведение отбраковки при перемещении иерархии навигации, которую я не мог исправить. Возможно, контроллеры UINavigation отражают класс своего верхнего контроллера и ведут себя по-другому?

Короче говоря, он действительно доступен только для чтения, и нет простого или простого обходного пути. Вы просто должны архитектовать вокруг.

Ответ 5

parentViewController предназначен для целей NavigationViewControllers и представления контроллеров модального представления, нет способа установить свойство без методов pushViewController или presentModalViewController. ParentViewController - это свойство readonly, которое может быть прочитано только классом UIViewController и классом UINavigationController, подклассы из них не будут иметь доступа к этому свойству.

Ответ 6

Похоже на вызов метода setParentViewController:.

[childViewController setParentViewController:self];

Однако это все еще генерирует предупреждение компилятора. Который, IMO, означает, что не делайте этого (вместо этого я подклассифицирован).