如何以编程方式显示视图

在这里输入图像说明

以上是我的故事板。 第一个视图连接到ViewController,第二个视图没有连接任何东西。 我知道如何显示第二个视图控制器,如果我有第一个button。 我可以点击并拖动button到第二个视图,创build一个segue。 但是,这一次,我必须在ViewController.m中以编程方式显示第二个视图控制器。 例如,在调用某个函数myFunc的时候,我想显示第二个视图控制器。 有人可以解释我怎么能做到这一点?

我想我需要知道以下几点:

  1. 如何在ViewController.m中引用第二个视图控制器
  2. 如何打开第二个视图控制器

谢谢!

更新:

//setSelectedDate is myFunc. It lives inside myView.m, which is a subview of UIView - (void)setSelectedDate:(NSDate *)newSelectedDate; { NSLog(@"override worked"); [super setSelectedDate:newSelectedDate]; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; UIViewController *firstController = [storyboard instantiateViewControllerWithIdentifier:@"InitialViewController"]; UIViewController *myController = [storyboard instantiateViewControllerWithIdentifier:@"MySecondViewController"]; [firstController presentViewController:myController animated:YES completion:nil]; } 

如果我这样做,我会得到以下警告:

警告:尝试呈现其视图不在窗口层次结构中的视图!

从这篇文章我相信这是因为我在错误的地方。 我该如何解决这个问题?

**更新2:我做了以下:**

 - (void)setSelectedDate:(NSDate *)newSelectedDate; { [super setSelectedDate:newSelectedDate]; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; UIViewController *firstController = [storyboard instantiateViewControllerWithIdentifier:@"InitialViewController"]; [firstController performSegueWithIdentifier:@"GoToSecondViewController" sender:firstController]; 

警告消失了,但视图控制器仍然没有显示。 是因为我在一个View而不是ViewController中调用这个吗?

您可以执行以下任一操作:

通过从firstViewController拖动到第二个,在storyboard中创build一个segue。 然后给这个segue一个名字(在Interface Builder的右边窗格的属性检查器下填充Identifier字段)。 让我们说“GoToSecondViewController”。

在你的myFunc方法(或函数)中,调用

 [self performSegueWithIdentifier:@"GoToSecondViewController" sender:nil]; 

要么

给你的第二个viewcontroller一个故事板ID。 从界面生成器中,点击你的第二个视图控制器。 在“身份检查器”下的右侧窗格中,填写故事板ID字段。 我们说“MySecondViewController”。

在你的myFunc方法(或函数)中执行以下操作:

 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]]; // or whatever your storyboard is called UIViewController *myController = [storyboard instantiateViewControllerWithIdentifier:@"MySecondViewController"]; [self presentViewController:myController animated:YES completion:nil]; // present it or push it if you have a navigation controller 

为了避免紧密耦合这些组件,下面是我该怎么做。

myView.h ,添加一个你的InitialViewController将符合的委托协议,并将该types的一个属性添加到myView类中:

 @class myView; @protocol myViewDelegate -(void)datePickerDidChangeValue:(myView*)view; @end @interface myView : UIView @property IBOutlet id<myViewDelegate> delegate; // ... other members ... @end 

并且在它的实现中调用setSelectedDate:方法中的委托方法:

 -(void)setSelectedDate:(NSDate*)selectedDate { _selectedDate = selectedDate; [self.delegate datePickerDidChangeValue:self]; } 

然后,将InterfaceBuilder中的委托属性设置为您的InitialViewController。 右键单击您的自定义视图,然后从delegate出口拖到您的ViewController:

Interface Builder的屏幕截图

然后,在InitialViewController.h中,将其设置为符合myViewDelegate协议:

 #import "myView.h" @interface InitialViewController : UIViewController<myViewDelegate> // ... members ... @end 

并实现这个委托方法,就像这样,假设你已经设置了这个答案中描述的标识符:

 -(void)datePickerDidChangeValue:(myView*)view { NSDate* theDate = view.selectedDate; // do whatever you want with this value UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]]; UIViewController *myController = [storyboard instantiateViewControllerWithIdentifier:@"MySecondViewController"]; [self presentViewController:myController animated:YES completion:nil]; }