Перезагрузка 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];
}

Это работает с одним исключением:

  1. Все переменные данные сохраняются от начальной загрузки, поэтому, когда главный экран снова появляется, у меня есть все предыдущие данные плюс новые данные.

призвание 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 ответ

Решение

Обычный способ передачи данных обратно на предыдущий контроллер - через делегирование. У вас должен быть протокол делегата в контроллере, который показывает связанные рецепты (в вашем примере), и начальный подробный контроллер должен установить себя в качестве делегата. Когда пользователь выбирает один из связанных элементов, вызовите метод делегата, который передаст обратно данные, необходимые для перезагрузки подробного контроллера.

Теперь за вашими исключениями,

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

    @property (сильный, неатомный) DetailViewController *vc;

И в вашем коде вы должны ссылаться на него с помощью self.vc, а не создавать локальную переменную (что вы делаете в опубликованном коде) с тем же именем, что и у свойства,

self.vc = detailViewControllerId;

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

  1. Вы действительно не должны вызывать viewDidLoad напрямую. Контроллер вызывает это, когда загружает свой вид. Поскольку вы в первую очередь не сказали, как загружать детальный контроллер, трудно сказать, почему вы получаете старые данные плюс новые. Что вы должны сделать, это установить массив, который вы используете для заполнения таблицы, значениями, которые вы отправляете обратно в методе делегата.
Другие вопросы по тегам