我基本上有一个使用RestKit
从远程服务器提取数据的Master-Detail应用程序。
DetailViewController
充当具有三个viewControllers的PageViewController
的数据源。我的问题只涉及其中两个,所以我将重点关注这一点。我会称这两个重要的viewControllers
:FirstViewController
和SecondViewController
。
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];
}
这有一个例外:
致电viewDidLoad
做了我所希望的事。 viewDidLoad
启动一系列API调用以从服务器获取数据,然后填充viewControllers
的内容PageViewController
。但是,我需要从头开始重新加载过去数据的东西。
有没有人有更好的建议来完成我想做的事情?感谢
========== EDIT ===============
以下是可能需要的更多信息。
从头开始,用户选择MasterViewController
中的一个单元格,该单元格触发DetailViewController
的segue。我正在使用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
来启动流程就很容易,但我不确定这是否合适。什么是最好的方法呢?
对小说感到抱歉,只是想澄清那些投入其中的人。
答案 0 :(得分:1)
将数据传递回先前控制器的常用方法是通过委派。您应该在控制器中有一个委托协议,显示相关的配方(在您的示例中),并且初始详细控制器应将自己设置为委托。当用户选择其中一个相关项时,调用委托方法,该方法将传回重新加载详细控制器所需的数据。
现在你的例外,
您收到该错误是因为您的属性声明错误 - 应该是
@property(强,非原子)DetailViewController * vc;
在您的代码中,您应该使用self.vc来引用它,而不是创建一个局部变量(这是您在发布的代码中所做的),其名称与属性相同,
self.vc = detailViewControllerId;
无论如何,你还不清楚你在使用那条线路做什么,因为你没有说明是什么detailViewControllerId。