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


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

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

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

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

6 13

6 ответов:

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

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

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

Решение таково:

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

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

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

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

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

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

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

Вы можете прочитать больше о "создании пользовательских контроллеров представления контента" вApple .

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

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

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

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

У меня есть представление контейнера, которое имеет 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];
}

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

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

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

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

Похоже, что вызов метода setParentViewController: работает.

[childViewController setParentViewController:self];

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