以编程方式切换视图

Posted

技术标签:

【中文标题】以编程方式切换视图【英文标题】:Switching Views Programmatically 【发布时间】:2012-10-29 23:46:02 【问题描述】:

我在 IB 中设置了一些视图控制器。一个具有大约 6 个单元格的 TableView(以编程方式填充)。然后还有 6 个视图控制器(每个单元格一个)。

我想让它在我的

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath



我可以将视图切换到与单击的单元格相关的任何视图。

所以如果他们点击cell1,它会转到view1,如果他们点击cell2,它会转到view2。

顺便说一句,这就是我初始化表的方式,它工作正常。

//tableview datasource delegate methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    return 1;

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    return showArray.count;

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

static NSString *CellIdentifier = @"Cell";

CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];


if(cell == nil)
    cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


cell.showLabel.text = [showArray objectAtIndex:indexPath.row];
cell.image.image = [UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]];
cell.seasonLabel.text = [seasonArray objectAtIndex:indexPath.row];

return cell;


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
return 106;

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:    (UITableViewRowAnimation)animation


NSIndexPath *newCellPath = [NSIndexPath indexPathForRow:showArray.count
                                              inSection:0];

[self.theatreView insertRowsAtIndexPaths:@[newCellPath]
                        withRowAnimation:UITableViewRowAnimationFade];



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath



【问题讨论】:

您的应用程序结构如何。它是否位于导航控制器中? @Bergasms 不,它有一个作为主菜单的视图控制器,它只是使用 UIButtons 从一个控制器转到另一个控制器 【参考方案1】:

我会根据您的应用程序的结构建议这两种方法之一。

[self.navigationController pushViewController:newViewController animated:YES];


[self presentModalViewController:newViewController animated:YES];

//for ios 6.0
[self presentViewController:newViewController animated:animated completion:NULL];

据我所知,您在主菜单的 .xib 文件中创建了很多 uiviewcontroller。那是对的吗?所以你将拥有 self.theatreViewController。然后,您可以将其作为按钮回调中的参数传递。例如

[self presentViewController:self.theatreViewController animated:animated completion:NULL];

如果我在这里的假设有误,请纠正我。

【讨论】:

presentModalViewController:animated: deprecated in iOS 6 apparantly.. 并且还收到警告不兼容的指针类型将 'TheatreViewController *_strong' 发送到'UIViewController 类型的参数我写的是 [self presentModalViewController: TheatreViewController animated:YES ]; 您需要将实际变量传递给presentModalViewController。例如 TheatreViewController *myviewController,你可以将 myviewController 传入。也很好地抓住了 ios6 的弃用,我忘记了这一点。相反,您使用 [self presentViewController:modalViewController animated:animated completion:NULL]; 这会起作用(您对答案的编辑)但是 theatreViewController 不是 Viewcontroller 的属性,所以我不能使用 self.theatreViewController 但是是的,你是对的,我有很多视图控制器我只想切换它们之间。编辑:现在单击按钮时出现此错误。 'NSInvalidArgumentException',原因:'应用程序试图在目标 上呈现一个 nil 模态视图控制器。 我认为这里的问题是由于某种原因它看到我添加的视图控制器为零,我不确定为什么 当你push一个viewController时检查它是否不是nil然后push。如果为 nil,则分配该 viewController【参考方案2】:

我不知道你的应用的结构,但我想你可以考虑一下:

- (UIViewController *)getViewControllerAtIndexPath:(NSIndexPath *)indexPath 
    //..you can use "switch" to return the view controller you want
    return ...;


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    UIViewController *controller = [self getViewControllerAtIndexPath:indexPath];
    //..push or present your controller

【讨论】:

【参考方案3】:

在此方法中使用 index path 属性: (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

喜欢

yourObject = [yourArray objectAtIndex:indexPath];

编辑:- 在您的 AppDelegate 中使用以下方法,执行以下操作:-

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

  

  self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.

  mHomeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mHomeViewController];
  [mHomeViewController release];

  self.window.rootViewController = navController;
  self.window.backgroundColor = [UIColor whiteColor];
  [self.window makeKeyAndVisible];
  [navController release];
  return YES;

现在,在您的 viewController - didSelectRowMethod 中,执行以下操作:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    NSString * object = [yourArray objectAtIndex:indexPath.row];

    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    if(newControllerInstance == nil) // check if it's nil, then initialize and alloc it.
   
      newControllerInstance = [[NewViewController alloc] initWithNibName:@"NewViewController" bundle:nil];
      [self.navigationController newControllerInstance animated:YES];
      [newControllerInstance release];
   

这应该可行。

【讨论】:

我知道如何找到索引,如果您阅读下面的 cmets,我的视图控制器似乎出于某种原因是 Nil。我不知道为什么 如果只想推送视图,使用 [self.navigationController pushViewController:ViewController animated:YES]; ,你初始化和分配你的视图控制器了吗? 我没有导航控制器,你说的初始化和分配是什么意思。你的意思是我有一个 -(id) init 之类的东西吗? 如果你想推送到一个视图控制器,你应该有一个导航控制器作为父级,你可以使用 self.navigationController pushViewController:ViewController 来推送到不同的视图,或者你可以使用 CATransitions (动画)。 我将如何初始化导航控制器@Angad

以上是关于以编程方式切换视图的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式切换 MVC 视图控制器 - iOS

在 Swift 中以编程方式切换视图

以编程方式从模态视图控制器切换父选项卡

以编程方式切换自定义视图(推送和弹出)

以编程方式切换子视图控制器:XLPagerTabStrip

在 Swift 中单击以编程方式切换到 TableViewCell 上的导航视图