Сохранение состояния iOS и просмотр контейнера
У меня есть контроллер представления в раскадровке, которая использует представление контейнера. У обоих установлены идентификаторы восстановления. Родитель сохраняется и восстанавливается очень хорошо. Ребенок, однако, нет. ни -encodeRestorableStateWithCoder:
или же -decodeRestorableStateWithCoder:
вызываются на дочернем контроллере представления.
Как правильно сохранить дочерние контроллеры представления, созданные с помощью контейнера представления? Я могу сохранить дочерний вид контроллера в родителях -encodeRestorableStateWithCoder:
, что приведет к его сохранению, но у меня нет способа использовать его во время восстановления.
2 ответа
Контейнерный контроллер представления "не сохраняет автоматически ссылки на любые содержащиеся дочерние контроллеры представления. Если вы реализуете пользовательский контроллер представления контейнера, вы должны кодировать дочерние объекты контроллера представления самостоятельно, если вы хотите, чтобы они были сохранены".
Есть простые правила, которые я нашел:
1. Встроенный (дочерний) контроллер вида должен быть уже создан и добавлен в родительский контроллер вида в процессе сохранения состояния. Таким образом, не нужно ничего делать, если вы используете раскадровку, иначе вам придется создать экземпляр дочернего контроллера представления и добавить его вручную:
-(void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"Did load");
MyChildViewController *childViewController = [MyChildViewController new];
[self addChildViewController:childViewController];
[childViewController didMoveToParentViewController:self];
self.childVC = childViewController;
}
Вы можете добавить дочерний вид на -viewDidLoad
или позже. использование self.childVC.view.frame = [self frameForChildController]; [self.view addSubview:self.childVC.view];
за это.
2. Вам не нужно сохранять дочерний контроллер представления в родительском -encodeRestorableStateWithCoder:
сам, но вы должны закодировать ссылку на этот объект, используя -encodeObject:forKey:
, Если у вас есть ссылка, вы можете сделать это так:
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
NSLog(@"Encode");
UIViewController *childViewController = self.childVC;
[coder encodeObject:childViewController forKey:@"ChildVC"];
[super encodeRestorableStateWithCoder:coder];
}
см. /questions/11549479/kontroller-dostupa-k-kontejneru-iz-roditelskoj-ios/11549500#11549500 чтобы получить ссылку на дочерний VC, если вы используете раскадровку. Или вы можете написать что-то простое, как это:
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
NSLog(@"Encode");
UIViewController *childViewController = [self.childViewControllers objectAtIndex:0]; //[self.childViewControllers lastObject];
[coder encodeObject:childViewController forKey:@"ChildVC"];
[super encodeRestorableStateWithCoder:coder];
}
3.Встроенный (дочерний) контроллер представления уже должен быть создан и добавлен в родительский контроллер представления в процессе восстановления состояния. Итак, если вы все сделали в первом абзаце, здесь больше нечего делать.
4. "В этом случае, однако, мы не декодируем дочерний контроллер представления. Мы могли бы, но на самом деле нам это не нужно. Объект MyChildViewController восстановит свое собственное состояние. Мы только закодировали эту ссылку, чтобы получить среду выполнения пройти цепочку до экземпляра MyChildViewController и выполнить сохранение и восстановление на нем ".
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
NSLog(@"Decode");
[super decodeRestorableStateWithCoder:coder];
}
Эта книга помогает мне понять сохранение состояния с помощью контейнерных представлений. Также ищите хороший пример для этой книги
Я думаю, что ответ в документации сказано:
"Класс UIViewController сохраняет ссылку на представленный контроллер представления и раскадровку (если есть), которая использовалась для создания контроллера представления. Контроллер представления также запрашивает представления в своей иерархии представления, чтобы сохранить любую соответствующую информацию. Однако этот класс не сохраняет автоматически ссылки на любые содержащиеся дочерние контроллеры представления. Если вы реализуете пользовательский контроллер представления контейнера, вы должны кодировать дочерние объекты контроллера представления самостоятельно, если вы хотите, чтобы они были сохранены."
Так что вы можете сделать что-то вроде этого:
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder {
[super encodeRestorableStateWithCoder:coder];
[self.myChildViewController encodeRestorableStateWithCoder:coder];
}
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder {
[super decodeRestorableStateWithCoder:coder];
[self.myChildViewController decodeRestorableStateWithCoder:coder];
}
А в MyChildViewController не звоните супер:)