如何以编程方式显示视图
以上是我的故事板。 第一个视图连接到ViewController,第二个视图没有连接任何东西。 我知道如何显示第二个视图控制器,如果我有第一个button。 我可以点击并拖动button到第二个视图,创build一个segue。 但是,这一次,我必须在ViewController.m中以编程方式显示第二个视图控制器。 例如,在调用某个函数myFunc的时候,我想显示第二个视图控制器。 有人可以解释我怎么能做到这一点?
我想我需要知道以下几点:
- 如何在ViewController.m中引用第二个视图控制器
- 如何打开第二个视图控制器
谢谢!
更新:
//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:
然后,在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]; }