2014-03-13 22 views
0

我基本上有一个Master-Detail应用程序,它利用RestKit从远程服务器提取数据。重新加载包含UIPageViewController的DetailViewController

DetailViewController充当具有三个viewController的PageViewController的数据源。我的问题只涉及其中的两个,所以我会专注于此。我会打电话给两个重要的viewControllersFirstViewControllerSecondViewController

FirstViewController显示在主视图中选择的项目的详细内容,基本上是图像和一些文本。滚动到SecondViewController将显示一个UITableView,其中包含与主视图中内容相关的项目。看到这个链接How to implement UIPageViewController that utilizes multiple ViewControllers为应用程序的类似故事板的图像。

为了阐明更多想象一个配方应用程序,您可以在其中选择一个配方在主场景中查看。细节场景显示所选配方。滚动到下一个页面会显示一个表格,其中包含与所选内容相关的食谱。

随着在这里建立的背景是我的问题:

我想设置的东西,以便用户可以选择在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调用以从服务器获取数据,然后填充PageViewController的内容viewControllers。不过,我需要的东西,基本上会重新加载它从一开始吹出过去的数据。

有没有人有更好的建议来完成我想要做的事情?由于

==========编辑===============

下面是一些可能需要更多的信息。

从头开始,用户选择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处理填充UIImageViewUITextField。同样,SecondViewController处理填充UITableView

现在为问题的肉...用户看到他们感兴趣的东西,并选择它。我使用didSelectRowAtIndexPath来获取我需要的服务器调用所需的信息,然后需要重新加载PageViewController。鉴于DetailViewControllerPVC的数据源,我需要数据源刷新/重新加载。我认为只需拨打viewDidLoad即可开始这一过程,但我不确定这是否合适。什么可能是最好的方式来做到这一点?

对不起,小说只是想澄清那些已经投入他们的意见。

回答

1

将数据传回前一个控制器的通常方法是通过委派。你应该在控制器中有一个委托协议来显示相关的配方(在你的例子中),并且初始细节控制器应该将自己设置为委托。当用户选择其中一个相关项目时,调用委托方法,它将传回重新加载细节控制器所需的数据。

现在到您的例外,

  1. 你得到这个错误,因为你的财产申报是错误的 - 它应该是,

    @property(强,非原子)DetailViewController * VC;

并在代码中,你应该是指它与self.vc,而不是创建一个局部变量(这是你在发布代码做什么)具有相同名称的属性,

self.vc = detailViewControllerId; 

无论如何你不知道你在做什么,因为你没有说什么detailViewControllerId。

  1. 你真的不应该直接调用viewDidLoad。控制器在加载视图时调用它。由于您没有说明如何加载细节控制器,所以很难说为什么要获取旧数据和新数据。你应该做的是设置你用来填充表格的数组,以便你在委托方法中返回的值。
+0

rdelmar,看来我对我的问题中的一些重要观点有点模糊。我必须离开我的电脑,直到明天晚上。我将澄清一些观点并添加一些额外的代码。感谢您的建议。 – Ben

+0

好的rdelmar,我添加了一些代码和解释。我发誓我试过你的DetailViewController的属性定义,它给了我一个错误,但现在它的作品,所以我一定有一个错字。我正在建立一个委托协议,用于传回数据。我也觉得我可以完成消除旧数据和新数据的任务。最后,我接受你的英雄38.4k的声望,并谦虚地问你现在如何重新加载场景,你首先看到我是如何做到的。 – Ben

+0

@Ben,我有点困惑,在用户在第二个控制器中选择一行之后,哪个调用服务器获得了重新加载细节控制器所需的信息?无论这种调用是什么,您都应该在实现委托方法时调用该方法。 – rdelmar

相关问题