我正在使用BookController类,它使用pagenumbers来跟踪当前视图。目前我正在按需创建每个视图控制器并以编程方式编写代码。我想访问我在StoryBoard中创建的视图控制器(xib文件),这样当我需要一个新页面时,它将访问我创建的第二个视图控制器。
// 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:@"icon@2x.png"]];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.center = CGPointMake(160.0f, 230.0f);
[controller.view addSubview:imageView];
return controller;
}
只是不确定如何调用访问我创建的xib文件并将其放入第一页(page = 0)。第二页(页面= 1)是我如何以编程方式绘制书中所有其他页面的示例。谢谢!
答案 0 :(得分:2)
请记住,故事板只是NIB的集合,它只是实例化每个视图的层次结构,并将出口连接到拥有的视图控制器。您不希望自己实例化Storyboard以创建单个视图控制器。当应用程序已经启动并且运行不同的实例时,正在做的是创建新实例。即使你确实将它们连接起来,它们也会连接到多余的实例,而不是你想要的实际实例。
我要做的是为SecondViewController创建一个单独的NIB文件,您将单独使用它。然后你需要将它们连接在一起。如果此代码在您需要访问的实例中,则只需将其传递给SecondViewController上的属性即可。或者你可能只是传递值,但很可能你会想要设置一个委托属性并为SecondViewController定义一个协议来回调创建它的实例。
对于您的代码,您只需使用以下代码加载NIB。
SecondViewController *vc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
vc.delegate = self;
您只需要定义该委托以及可能需要向新创建的视图控制器提供数据所需的任何属性。
下面是我最近使用Storyboard为SideBar界面创建的委托设置示例。我有一个容器视图,用于Home VC中的Header VC。这个Header VC可能就像你的SecondViewController,因为我无法在Storyboard中连接它,所以我用代码做了。首先,我在Header VC上创建了一个委托属性。
@protocol IFHeaderDelegate;
@interface IFHeaderViewController : UIViewController
@property (nonatomic, assign) IBOutlet id<IFHeaderDelegate> delegate;
@end
@protocol IFHeaderDelegate <NSObject>
- (void)headerViewDidToggleSideBar:(IFHeaderViewController *)sender;
@end
然后,当点击按钮时,我使用委托进行回调。 (请注意,我使用NSAssert来验证委托是否只是为了让我在错过它时提醒我。)
#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中触发嵌入segue时,我所做的是在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