Перезагрузка DetailViewController, который содержит UIPageViewController
У меня в основном есть приложение Master-Detail, которое использует RestKit
вытащить данные с удаленного сервера.
DetailViewController
действует как источник данных для PageViewController
это имеет три viewControllers. Мой вопрос касается только двух из них, поэтому я остановлюсь на этом. Я назову два важных viewControllers
: FirstViewController
а также SecondViewController
,
FirstViewController
отображает подробное содержание элемента, выбранного в главном представлении, в основном изображение и некоторый текст. Прокрутка до SecondViewController
отображает UITableView
который содержит элементы, связанные с содержимым в главном представлении. См. Эту ссылку Как реализовать UIPageViewController, который использует несколько ViewController для изображения, похожего на раскадровку приложения.
Чтобы прояснить это немного, представьте приложение с рецептами, в котором вы выбираете рецепт для просмотра на главной сцене. Подробная сцена отображает выбранный рецепт. Прокрутка до следующей страницы отображает таблицу с рецептами, связанными с выбранным.
С установленным фоном вот мой вопрос:
Я пытаюсь настроить все так, чтобы пользователь мог выбрать ячейку в tableview
и DetailViewController
перезагрузится с данными из выбранной ячейки. Например, пользователь видит интересующий его связанный рецепт, выбирает ячейку, и представление перезагружается на главной странице в PageViewController
с данными из выбранной ячейки.
Я чувствовал, что самый простой способ сделать это может просто передать некоторые необходимые переменные в DetailViewController и вызвать viewDidLoad
вот так.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Grab index object at index path
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
//Initialize DVC class to utilize variables and methods
DetailViewController *vc = detailViewControllerId;
vc.articleId = [object valueForKey:@"articleId"];
vc.imageUrl = [object valueForKey:@"image"];
//Reload the DetailViewController
[vc viewDidLoad];
}
Это работает с одним исключением:
- Все переменные данные сохраняются от начальной загрузки, поэтому, когда главный экран снова появляется, у меня есть все предыдущие данные плюс новые данные.
призвание viewDidLoad
сделал то, что я надеялся. viewDidLoad
запускает последовательность вызовов API для получения данных с сервера, а затем заполняет контент viewControllers
из PageViewController
, Однако мне нужно что-то, что по существу перезагрузит его с самого начала, стирая прошлые данные.
У кого-нибудь есть лучшие предложения, чтобы выполнить то, что я пытаюсь сделать? Спасибо
==========EDIT===============
Вот еще немного информации, которая может понадобиться.
С самого начала пользователь выбирает ячейку в MasterViewController
который вызывает переход к DetailViewController
, я использую prepareForSegue
передать необходимые данные в DetailViewController
,
DetailViewController
действует как источник данных для PageViewController
так когда viewDidLoad
называется в DetailViewController
серия методов называется заполнить элементы источника данных, необходимые в PageViewController
, Вот основы.
DetailViewController.h
@interface DetailViewController : UIViewController<UINavigationControllerDelegate, UIPageViewControllerDataSource>
{
}
@property (strong, nonatomic) UIPageViewController *pageViewController;
@property (strong, nonatomic) NSURL *imageUrl;
@property (strong, nonatomic) NSData *passingPhotoData; //used to pass to the pageViewController;
@property (strong, nonatomic) NSAttributedString *passingString; //passes text to pageViewController;
@property (strong, nonatomic) NSArray *vc1;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) NSString *articleId;
@end
DetailViewController.m
-(void)viewDidLoad
{
//There is other things in the method but these are the only significant line for the question.
//The method call below is to start a call to the server to get the information needed about the cell that was selected.
vc1 = [[NSArray alloc] init];
[self getDetailInfoFromServer]
}
-(void)getDetailInfoFromServer
{
//Here I make a call to the server using Restkit… it is not significant for the question so I'll leave it out.
//The data that is retrieved from this server call is everything that I will use to populate the FirstViewController which is again an image and some text.
//If the call to the server was successful RestKit maps out the data in Core Data and I move on to the next method.
[self getInfoRelatedToDetailView]
}
-(void)getInfoRelatedToDetailView
{
//The data that is retrieved from this server call is everything that I will use to populate the SecondViewController.
//The SecondViewController is a tableView and the data retrieved will be an array of images and the associated text.
//If the call to the server was successful Restkit will again map the data into Core Data entities and I move on to the next method.
[self getTextForFVC]
}
-(void)getTextForFVC
{
//In this method I fetch the text from Core Data that was received back in getDetailInfoFromServer.
//It is all HTML which I parse to a string using DTCoreText and finally set passingString equal to the result.
//passingString is one of the variables I use to pass needed info to the FirstViewController.
self.passingString = parsedString
//At this point I start the setup of the pageViewController, this is just standard stuff that goes with a PageViewController
FirstViewController *selectedController = [self populateFirstViewController];
vc1 = @[selectedController];
// Create page view controller
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource = self;
[self.pageViewController setViewControllers:vc1 direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
//Notice above the call to a method populateFirstViewController That is where I go next.
-(FirstViewController *)populateFirstViewController
{
//This is a simple method that gets called whenever the PageViewController delegate methods deem it necessary to load the FirstViewController.
FirstViewController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstController"];
fvc.imageData = self.passingPhotoData; //This variable was set earlier but I left out the code
fvc.nodeText = self.passingString;
return nvc;
}
-(SecondViewController *)populateSecondViewController
{
//This method is like the one above, it is called when the PVC delegate methods deem it necessary to load the page
SecondViewController *svc =[self.storyboard instantiateViewControllerWithIdentifier:@"SecondController"];
//Here are some of the variables I pass in
svc.managedObjectContext = self.managedObjectContext;
cvc.detailViewControllerId = self; //This line allows me to call the viewDidLoad method for the DetailViewController from the SecondViewController.
return cvc;
}
После того, как все это состоится PageViewController
появляется с данными, полученными с сервера. FirstViewController обрабатывает заполнение UIImageView
а также UITextField
, Аналогично, SecondViewController обрабатывает заполнение UITableView
,
Теперь о сути вопроса... Пользователь видит в таблице то, что ему интересно, и выбирает ее. Я использую didSelectRowAtIndexPath
чтобы получить информацию, необходимую для звонков на сервер, а затем PageViewController
перезагрузить. Учитывая, что DetailViewController
является источником данных для PVC
Мне нужен источник данных для обновления / перезагрузки. Я думал, что будет просто позвонить viewDidLoad
чтобы начать процесс, но я не уверен, что это правильный путь. Что может быть лучшим способом сделать это?
Извините за Роман, просто хотел уточнить для тех, кто внес на их вклад.
1 ответ
Обычный способ передачи данных обратно на предыдущий контроллер - через делегирование. У вас должен быть протокол делегата в контроллере, который показывает связанные рецепты (в вашем примере), и начальный подробный контроллер должен установить себя в качестве делегата. Когда пользователь выбирает один из связанных элементов, вызовите метод делегата, который передаст обратно данные, необходимые для перезагрузки подробного контроллера.
Теперь за вашими исключениями,
Вы получаете эту ошибку, потому что декларация вашего свойства неверна - должно быть,
@property (сильный, неатомный) DetailViewController *vc;
И в вашем коде вы должны ссылаться на него с помощью self.vc, а не создавать локальную переменную (что вы делаете в опубликованном коде) с тем же именем, что и у свойства,
self.vc = detailViewControllerId;
В любом случае, не совсем понятно, что вы делаете с этой строкой, поскольку вы не говорите, что такое detailViewControllerId.
- Вы действительно не должны вызывать viewDidLoad напрямую. Контроллер вызывает это, когда загружает свой вид. Поскольку вы в первую очередь не сказали, как загружать детальный контроллер, трудно сказать, почему вы получаете старые данные плюс новые. Что вы должны сделать, это установить массив, который вы используете для заполнения таблицы, значениями, которые вы отправляете обратно в методе делегата.