ios - 如何以编程方式调用 View Controller 以获取其在 Storyboard中的 View ?

标签 ios storyboard viewcontroller

我正在使用 BookController 类,它使用页码来跟踪当前 View 。目前,我正在按需创建每个 View Controller 并以编程方式编写代码。我想访问我在 Storyboard(xib 文件)中创建的 View Controller ,这样当我需要一个新页面时,它将访问我创建的第二个 View Controller 。

// Provide a view controller on demand for the given page number

- (id) viewControllerForPage: (int) pageNumber {

if ((pageNumber < 0) || (pageNumber > 31)) return nil;


if(pageNumber == 0){

      //here is where I want to access the entire xib file that the SecondViewController is connected with     
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
    SecondViewController *myVC = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

    myVC = [BookController rotatableViewController];

    return myVC;

     }
else if(pageNumber == 1){


// Establish a new controller
   UIViewController *controller = [BookController rotatableViewController];


// Add a text view
UITextView *textview = [[UITextView alloc] initWithFrame:(CGRect){.size = CGSizeMake(100.0f,100.0f)}];
textview.text = [NSString stringWithFormat:@"This is dedicated to people"];
textview.font = [UIFont fontWithName:@"Futura" size:18.0f];
textview.center = CGPointMake(475.0f, 700.0f);
[controller.view addSubview:textview];

     // Add a label
UILabel *textLabel = [[UILabel alloc] initWithFrame:(CGRect){.size = CGSizeMake(200.0f, 200.0f)}];
textLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
textLabel.text = [NSString stringWithFormat:@"1"];
textLabel.font = [UIFont fontWithName:@"Futura" size:18.0f];
textLabel.center = CGPointMake(475.0f, 985.0f);
[controller.view addSubview:textLabel];


    // Add it as an image
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="78111b1716384a005608161f" rel="noreferrer noopener nofollow">[email protected]</a>"]];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    imageView.center = CGPointMake(160.0f, 230.0f);
[controller.view addSubview:imageView];


return controller;
}

Just not sure how to make a call to access that xib file i've created and make it into the first page (page=0). The second page (page =1) is an example of how i have drawn all the other pages in my book programmatically. Thanks!

最佳答案

请记住, Storyboard只是 NIB 的集合,它只是实例化每个 View 的层次结构并将导出连接到所属的 View Controller 。您不想自己实例化 Storyboard来创建单个 View Controller 。其作用是在应用程序已启动并与不同实例一起运行时创建新实例。即使您确实将它们连接起来,它们也会连接到冗余的实例,而不是您想要的实际实例。

我会做的是为 SecondViewController 创建一个单独的 NIB 文件,您将单独使用它。然后您需要将其连接在一起。如果此代码位于您需要访问的实例中,您只需将其传递给 SecondViewController 上的属性即可。或者也许您只是传递值,但很可能您需要设置委托(delegate)属性并为 SecondViewController 定义一个协议(protocol)来回调创建它的实例。

对于您的代码,您只需使用以下代码加载 NIB。

SecondViewController *vc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
vc.delegate = self;

您只需要定义该委托(delegate)以及可能需要的任何属性,以便为新创建的 View Controller 提供数据。

下面是我最近使用 Storyboard 为 SideBar 界面创建的委托(delegate)设置示例。我有一个位于 Home VC 中的 Header VC 的容器 View 。这个 Header VC 可能就像你的 SecondViewController 因为我无法在 Storyboard 中连接它,所以我用代码完成了它。首先,我在 Header VC 上创建了一个委托(delegate)属性。

@protocol IFHeaderDelegate;

@interface IFHeaderViewController : UIViewController

@property (nonatomic, assign) IBOutlet id<IFHeaderDelegate> delegate;

@end

@protocol IFHeaderDelegate <NSObject>

- (void)headerViewDidToggleSideBar:(IFHeaderViewController *)sender;

@end

然后,当点击按钮时,我使用委托(delegate)进行回调。 (请注意,我使用 NSAssert 来验证委托(delegate)是否已定义,只是为了在我错过它时提醒我。)

#import "IFHeaderViewController.h"

@interface IFHeaderViewController ()

@end

@implementation IFHeaderViewController

- (IBAction)siderBarButtonTapped:(id)sender {
    NSAssert(self.delegate != nil, @"Delegate must be defined!");

    if (self.delegate != nil) {
        [self.delegate headerViewDidToggleSideBar:self];
    }
}

@end

但是为了将其连接起来,我必须从 Home VC 设置代表,而我无法从 Storyboard 中做到这一点。当嵌入转场在prepareForSegue中被触发时,我所做的是在Home VC中设置它。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
   DebugLog(@"segue.identifier: %@", segue.identifier);

   if ([@"HomeHeader" isEqualToString:segue.identifier]) {
       NSAssert([segue.destinationViewController isKindOfClass:[IFHeaderViewController class]], @"Destination VC must be the Header VC");
       IFHeaderViewController *headerVC = (IFHeaderViewController *)segue.destinationViewController;
       headerVC.delegate = self;
   }
}

您可以在 GitHub 上找到完整的项目:https://github.com/brennanMKE/Interfaces/tree/master/SideBar

关于ios - 如何以编程方式调用 View Controller 以获取其在 Storyboard中的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13695931/

相关文章:

ios - 移动到另一个 swift 文件时 UIAlertController 不显示

swift - 尝试在 View Controller 之外使用 TextView 时出错

ios - Swift 中不可见的 Objective-C 协议(protocol)方法

ios - 在基本本地化中找不到 main.storyboard 字符串

swift - 在 swift 中以编程方式呈现 View Controller

ios - iPhone 6 plus 的屏幕尺寸问题

uiscrollview - initWithCoder 返回框架属性 0 值

iphone - NSRunLoop 和 NSAutoreleasePool,它们是如何交互的?

ios - 是否有必要在 UIView.animateWithDuration(...) 的闭包中使用 [unowned self]?

iphone - 在 Xcode 4.2 中启用崩溃日志符号化