如何从 UITableViewController 转到多个视图控制器
Posted
技术标签:
【中文标题】如何从 UITableViewController 转到多个视图控制器【英文标题】:How to go from UITableViewController to multiple View Controllers 【发布时间】:2013-11-16 13:34:23 【问题描述】:我是一名新的 ios 开发人员,当我为 Recipes 制作项目时,我遇到了这个问题,我需要从每个单元格转到一个单独的视图控制器,每个视图控制器都有一组图像,它显示为 UIPageViewController
。
这是我在第一个视图控制器上调用的数组 (RecipeViewController
)
- (void)viewDidLoad
[super viewDidLoad];
// Initialize table data
Recipe *recipe1 = [Recipe new];
recipe1.name = @"Egg Benedict";
recipe1.prepTime = @"30 min";
recipe1.imageFile = @"egg_benedict.jpg";
recipe1.ingredients = [NSArray arrayWithObjects:@"2 fresh English muffins", @"4 eggs", @"4 rashers of back bacon", @"2 egg yolks", @"1 tbsp of lemon juice", @"125 g of butter", @"salt and pepper", nil];
Recipe *recipe2 = [Recipe new];
recipe2.name = @"Mushroom Risotto";
recipe2.prepTime = @"30 min";
recipe2.imageFile = @"mushroom_risotto.jpg";
recipe2.ingredients = [NSArray arrayWithObjects:@"1 tbsp dried porcini mushrooms", @"2 tbsp olive oil", @"1 onion, chopped", @"2 garlic cloves", @"350g/12oz arborio rice", @"1.2 litres/2 pints hot vegetable stock", @"salt and pepper", @"25g/1oz butter", nil];
Recipe *recipe3 = [Recipe new];
recipe3.name = @"Full Breakfast";
recipe3.prepTime = @"20 min";
recipe3.imageFile = @"full_breakfast.jpg";
recipe3.ingredients = [NSArray arrayWithObjects:@"2 sausages", @"100 grams of mushrooms", @"2 rashers of bacon", @"2 eggs", @"150 grams of baked beans", @"Vegetable oil", nil];
Recipe *recipe4 = [Recipe new];
recipe4.name = @"Hamburger";
recipe4.prepTime = @"30 min";
recipe4.imageFile = @"hamburger.jpg";
recipe4.ingredients = [NSArray arrayWithObjects:@"400g of ground beef", @"1/4 onion (minced)", @"1 tbsp butter", @"hamburger bun", @"1 teaspoon dry mustard", @"Salt and pepper", nil];
Recipe *recipe5 = [Recipe new];
recipe5.name = @"Ham and Egg Sandwich";
recipe5.prepTime = @"10 min";
recipe5.imageFile = @"ham_and_egg_sandwich.jpg";
recipe5.ingredients = [NSArray arrayWithObjects:@"1 unsliced loaf (1 pound) French bread", @"4 tablespoons butter", @"2 tablespoons mayonnaise", @"8 thin slices deli ham", @"1 large tomato, sliced", @"1 small onion", @"8 eggs", @"8 slices cheddar cheese", nil];
Recipe *recipe6 = [Recipe new];
recipe6.name = @"Creme Brelee";
recipe6.prepTime = @"1 hour";
recipe6.imageFile = @"creme_brelee.jpg";
recipe6.ingredients = [NSArray arrayWithObjects:@"1 quart heavy cream", @"1 vanilla bean, split and scraped", @"1 cup vanilla sugar", @"6 large egg yolks", @"2 quarts hot water", nil];
Recipe *recipe7 = [Recipe new];
recipe7.name = @"White Chocolate Donut";
recipe7.prepTime = @"45 min";
recipe7.imageFile = @"white_chocolate_donut.jpg";
recipe7.ingredients = [NSArray arrayWithObjects:@"3 1/4 cups flour", @"2 teaspoons baking powder", @"1/4 teaspoon salt", @"2 beaten eggs", @"2/3 cup sugar", @"2 ounces melted white chocolate", @"1/2 cup milk", nil];
Recipe *recipe8 = [Recipe new];
recipe8.name = @"White Chocolate Mocha";
recipe8.prepTime = @"5 min";
recipe8.imageFile = @"starbucks_coffee.jpg";
recipe8.ingredients = [NSArray arrayWithObjects:@"2/3 cup whole milk", @"6 tablespoons white chocolate chips", @"coffee", @"whipped cream", nil];
Recipe *recipe9 = [Recipe new];
recipe9.name = @"Vegetable Curry";
recipe9.prepTime = @"30 min";
recipe9.imageFile = @"vegetable_curry.jpg";
recipe9.ingredients = [NSArray arrayWithObjects:@"1 tablespoon olive oil", @"1 onion, chopped", @"2 cloves garlic", @"2 1/2 tablespoons curry powder", @"2 quarts hot water", nil];
Recipe *recipe10 = [Recipe new];
recipe10.name = @"Instant Noodle with Egg";
recipe10.prepTime = @"8 min";
recipe10.imageFile = @"instant_noodle_with_egg.jpg";
recipe10.ingredients = [NSArray arrayWithObjects:@"1 pack of Instant Noodle", @"2 eggs", nil];
Recipe *recipe11 = [Recipe new];
recipe11.name = @"Noodle with BBQ Pork";
recipe11.prepTime = @"20 min";
recipe11.imageFile = @"noodle_with_bbq_pork.jpg";
recipe11.ingredients = [NSArray arrayWithObjects:@"1 pack of Instant Noodle", @"BBQ pork", @"Salt and Pepper", nil];
Recipe *recipe12 = [Recipe new];
recipe12.name = @"Japanese Noodle with Pork";
recipe12.prepTime = @"20 min";
recipe12.imageFile = @"japanese_noodle_with_pork.jpg";
recipe12.ingredients = [NSArray arrayWithObjects:@"1 pack of Japanese Noodle", @"2 green onions", @"2 garlic cloves, minced", @"4 boneless pork loin chops", nil];
Recipe *recipe13 = [Recipe new];
recipe13.name = @"Green Tea";
recipe13.prepTime = @"5 min";
recipe13.imageFile = @"green_tea.jpg";
recipe13.ingredients = [NSArray arrayWithObjects:@"Green tea", nil];
Recipe *recipe14 = [Recipe new];
recipe14.name = @"Thai Shrimp Cake";
recipe14.prepTime = @"1.5 hours";
recipe14.imageFile = @"thai_shrimp_cake.jpg";
recipe14.ingredients = [NSArray arrayWithObjects:@"8 oz (250g) peeled and deveined raw shrimp", @"2 tablespoons red curry paste", @"1 large egg", @"2 teaspoon fish sauce", @"1 tablespoon sugar", @"2 tablespoons coconut milk", @"2 tablespoons roughly chopped Thai basil leaves", nil];
Recipe *recipe15 = [Recipe new];
recipe15.name = @"Angry Birds Cake";
recipe15.prepTime = @"4 hours";
recipe15.imageFile = @"angry_birds_cake.jpg";
recipe15.ingredients = [NSArray arrayWithObjects:@"12 tablespoons (1 1/2 sticks) unsalted butter", @"2 1/2 cups all-purpose flour", @"1 tablespoon baking powder", @"1 teaspoon salt", @"1 3/4 cups sugar", @"2 large eggs, plus 3 large egg yolks", @"1 cup of milk", nil];
Recipe *recipe16 = [Recipe new];
recipe16.name = @"Ham and Cheese Panini";
recipe16.prepTime = @"10 min";
recipe16.imageFile = @"ham_and_cheese_panini.jpg";
recipe16.ingredients = [NSArray arrayWithObjects:@"2 tablespoons unsalted butter", @"4 cups thinly sliced shallots", @"2 teaspoons fresh thyme", @"1/4 cup grainy Dijon mustard", @"8 slices rustic white bread", @"8 slices Gruyere cheese", @"8 ounces sliced cooked ham", nil];
recipes = [NSArray arrayWithObjects:recipe1, recipe2, recipe3, recipe4, recipe5, recipe6, recipe7, recipe8, recipe9, recipe10, recipe11, recipe12, recipe13, recipe14, recipe15, recipe16, nil];
所以当我按下“Egg Benedict”时,我需要转到带有图像数组的视图控制器,当我选择“Mushroom Ristto”时,转到另一个带有另一个图像数组的视图控制器,依此类推,对于我拥有的每 16 个数组。
我使用prepareForSegue
和代码如下
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([segue.identifier isEqualToString:@"themeDetails"])
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
ThemeDetailViewController *destViewController = segue.destinationViewController;
destViewController.theme = [titleLabel objectAtIndex:indexPath.row];
如果这正确或需要修改 我的(`ReciepeViewController.h)如下
@property (nonatomic, strong) ReciepeDetailViewController *reciepeDetailController;
请帮帮我;我在 google 和 youtube 上搜索了很多次,但没有得到任何东西
【问题讨论】:
为什么每次都跳转到不同的视图控制器?改为使用具有动态内容的视图控制器。 你能给我解释一下吗 我现在得走了,但如果我回来没有答案,我可以发一个。 【参考方案1】:您应该创建一个动态表格视图。
我建议对您的代码进行以下改进:
首先,我将创建一个包含您的食谱的 JSON 文件,该文件将成为应用程序包中的资源文件:
创建一个包含以下内容的文件“recipes.json”:
[
"preparation_time": 30,
"image_url": "egg_benedict.jpg",
"name": "Egg Benedict",
"ingredients": [
"2 fresh English muffins",
"4 eggs",
"4 rashers of back bacon",
"2 egg yolks",
"1 tbsp of lemon juice",
"125 g of butter",
"salt and pepper"
]
,
"preparation_time": 30,
"image_url": "mushroom_risotto.jpg",
"name": "Mushroom Risotto",
"ingredients": [
"1 tbsp dried porcini mushrooms",
"2 tbsp olive oil",
"1 onion, chopped",
"2 garlic cloves",
"350g/12oz arborio rice",
"1.2 litres/2 pints hot vegetable stock",
"salt and pepper",
"25g/1oz butter"
]
]
(注意:我只将您的代码示例中的两个配方放入 JSON 文件)
然后,在 viewDidLoad
中的视图控制器中加载配方并创建一个 JSON 表示,它是一个字典数组:
NSBundle* mainBundle = [NSBundle mainBundle];
NSURL* recipesDataURL = [mainBundle URLForResource:@"recipes" withExtension:@"json"];
if (recipesDataURL)
NSData* data = [NSData dataWithContentsOfURL: recipesDataURL];
if (data)
NSError* error;
NSArray* recipes = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
if (recipes == nil)
// error: couldn't parse the JSON
return;
self.recipes = recipes;
else
// error: couldn't load the data with the given URL
return;
else
// error: couldn't locate the resource in the bundle
return;
self.recipes
是视图控制器的一个属性,它是一个配方数组 (NSDictionary)。
配方本身就是NSDictionary
。如果需要,您可以创建一个专用类 Recipe
并初始化一个配方对象(例如 initWithParameters:
使用包含“参数”的字典。但是,使用 NSDictionary 作为配方对象可能完全足够了。
如果使用动态表格视图,则需要实现一些委托方法。官方文档有更多信息,请查看有关 UITableView 的各种可用主题:UITableView Programming Guide for iOS
基本上,作为一个快速开始,您的 TableViewDataSource
代表将访问数组 self.recipes
以获取 行数 和 recipe 对象的属性建立一个细胞。例如:
UITableViewDataSource 委托:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [self.recipes count];
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:@"MyIdentifier"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSDictionary* recipe = [self.recipes objectAtIndex:indexPath.row];
cell.textLabel.text = recipe[@"name];
return cell;
编辑:
您可以显示详细视图,该视图显示配方的所有详细信息,如其他答案中所示。我建议以下:
您的 Detail View Controller 有一个 recipe
类型为 NSDictionary
的公共属性:
@property (nonatomic, strong) NSDictionary* recipe;
当您不使用故事板时,您可以按如下方式显示详细视图控制器:
在您的 TableViewController.m 中:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary* recipe = [self.recipes objectAtIndex:[indexPath row]];
ShowRecipeViewController* viewController = (ShowRecipeViewController*)[[ShowRecipeViewController alloc] initWithNibName:@"ShowRecipeViewController" bundle:nil];
viewController.recipe = recipe;
[[self navigationController] pushViewController: viewController animated:YES];
不过,我建议使用情节提要。在这种情况下,细节视图控制器将获取prepareForSegue:sender:
中设置的属性recipe
。
另见:Passing data between View Controllers using Segue
【讨论】:
请告诉我可以为每个视图控制器放置新数组的位置;或者我创建了大约 16 个视图控制器,之后每个视图控制器都有不同的图像数组 你有一个表视图控制器和一个细节视图控制器。表格视图可能只显示配方的名称。如果用户在表格视图中的单元格上按标签,表格视图会创建一个新的ShowRecipeViewController
。然后,表格视图将 ShowRecipeViewController 的属性recipe
分配给当前选定的recipe。不久之后,ShowRecipeViewController 将根据其属性recipe
在viewWillAppear
或viewDidLoad
中设置其UI 元素。因此,您只需要详细视图控制器 (ShowRecipeViewController
) 的 ONE 类和它的 ONE 实例。
我现在试试这个方法,我会通知你的;但如果您有更多详细信息,请提供给我
我有一个错误 NSArray* recipes = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];可能误认为 &error;那你能解释一下这是否正确吗?
示例中有一个“错误”,我会修复它。然而,与往常一样,“代码示例”只是说明一个概念或解决方案的想法。不要总是期望示例代码——直接在 SO 编辑器中编写——总是可以毫无问题地编译;)上面的问题很容易解决。一分钟...【参考方案2】:
您有一个更好的选择,请转到单个 ViewController
并根据您的数据使其动态化。但是,当您想为各个数据使用多个 ViewController
时,只需执行以下操作...
在你的Recipe
接口中添加一个属性并合成它
@property (nonatomic, retain) UIViewController *MyViewController;
现在在您的 viewDidLoad
方法中执行以下操作
-(void)viewDidLoad
[super viewDidLoad];
ObjectHolderArray=[[NSMutableArray alloc] init]; // it's mutable array for holding all the object of recipe which we are going to create
Recipe *recipe1 = [Recipe new];
recipe1.name = @"Egg Benedict";
recipe1.prepTime = @"30 min";
recipe1.imageFile = @"egg_benedict.jpg";
recipe1.ingredients = [NSArray arrayWithObjects:@"2 fresh English muffins", @"4 eggs", @"4 rashers of back bacon", @"2 egg yolks", @"1 tbsp of lemon juice", @"125 g of butter", @"salt and pepper", nil];
recipe1.MyViewController=[[eggBenedictViewController alloc] init]; //set your respective viewController
[ObjectHolderArray addObject:recipe1]; // add your object to your array
Recipe *recipe2 = [Recipe new];
recipe2.name = @"Mushroom Risotto";
recipe2.prepTime = @"30 min";
recipe2.imageFile = @"mushroom_risotto.jpg";
recipe2.ingredients = [NSArray arrayWithObjects:@"1 tbsp dried porcini mushrooms", @"2 tbsp olive oil", @"1 onion, chopped", @"2 garlic cloves", @"350g/12oz arborio rice", @"1.2 litres/2 pints hot vegetable stock", @"salt and pepper", @"25g/1oz butter", nil];\
recipe1.MyViewController=[[mushroomRisottoViewController alloc] init]; //set your respective viewController
[ObjectHolderArray addObject:recipe2]; // add your object to your array
// and so on
现在在 didSelectRowAtIndexPath 中执行以下操作
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Recipe *recipeObject=[ObjectHolderArray objectAtIndex:[indexpath row]]; //get the selected recipe object
UIViewController *myController=(UIViewController *)[recipeObject MyViewController];
// Now you have your respective viewcotroller and also all the required data for going to next viewController
// then what you are waiting for? simply push your viewcontroller
【讨论】:
我知道我会用我将在不同的 viewController 上创建的数组替换 objectHolderArray;所以在那之后我必须在 viewdidload 上写下所有的数组 这并不意味着你已经在viewDidLoad上写了所有的数组。但是在调用 table view deligates 方法之前,你必须填充你的数组。 所以在调用之前我会在 eggBenedictViewController 和蘑菇RisottoViewController 上创建数组;对吗? 是的,您必须在调用它们之前准备好您的视图控制器。 我的详细视图有 uipageviewcontroller 所以objectHolderArray 将被更改为不同viewController 内的数组名称;我是对的?以上是关于如何从 UITableViewController 转到多个视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
如何从包含我的 UIViewController 的 UITableViewController 显示新视图?
如何将数据从 uitableviewcontroller 发送到 uitableviewcell
如何从 UITableViewController 中的静态单元格获取 textFields?迅速
如何从 Modal ViewController 重新加载父 UITableViewController 中的数据