如何以编程方式显示视图

时间:2014-10-26 22:45:07

标签: ios objective-c iphone

enter image description here

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

我想我需要了解以下内容:

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

    更新

    //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];
    }
    

    如果我在上面做的话,我会收到以下警告:

    警告:尝试显示其视图不在窗口层次结构中!

    从此post我相信它是因为我在错误的地方做这件事。我该如何解决这个问题?

    **更新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吗?

2 个答案:

答案 0 :(得分:2)

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

通过从firstViewController拖动到第二个控件,在故事板中创建一个segue。然后为该segue命名(填写Identifier字段,在Interface Builder右窗格的Attributes inspector下)。让我们说" GoToSecondViewController"。

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

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

OR

为您的第二个视图控制器提供一个故事板ID。在界面构建器中,单击第二个viewcontroller。在"身份检查员"下的右侧窗格中;填写Storyboard 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

答案 1 :(得分:1)

为了避免紧密耦合这些组件,我就是这样做的。

myView.h中,添加InitialViewController符合的委托协议,并将该类型的属性添加到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中的delegate属性设置为InitialViewController。右键单击自定义视图,然后从delegate插座拖动到ViewController:

Screenshot of Interface Builder

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

#import "myView.h"

@interface InitialViewController : UIViewController<myViewDelegate>
// ... members ... 
@end

并实现该委托方法,如下所示,假设您已按this answer中所述设置标识符:

-(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];
}