UISplitView Interface Builder nib 对象未分配

发布于 2024-10-16 09:01:58 字数 6147 浏览 2 评论 0原文

我目前正在使用 UISplitView 控制器,因为我必须让其中一些控制器在 UITabBarController 中工作。 经过几次尝试,我终于找到了一种方便的方法,我遇到的唯一问题是我必须手动实例化我的详细信息和主视图,尽管它们在 IB 中配置并链接良好。

以下是我的做法:

在 MainWindow.xib 中初始化 UITabBarCOntroller 并设置选项卡栏项目。

我的第一个选项卡控制器继承自 UISplitViewController 并使用 xib 设置。 这是这个 FirstViewController 类的实现

#import "FirstSplitViewController.h"
#import "MasterSplitViewController.h"
#import "DetailSplitViewController.h"


@implementation FirstSplitViewController

@synthesize detailSplitViewController,masterSplitViewController;



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

/*  
masterSplitViewController = [[[MasterSplitViewController alloc] initWithNibName:@"MasterSplitViewController" bundle:nil] autorelease];
detailSplitViewController = [[[DetailSplitViewController alloc] initWithNibName:@"DetailSplitViewController" bundle:nil] autorelease];
*/

self.viewControllers = [NSArray arrayWithObjects:masterSplitViewController, detailSplitViewController , nil];
self.delegate = detailSplitViewController;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[super dealloc];
}


@end

这是我的 MasterSplitview 实现

#import "MasterSplitViewController.h"


@implementation MasterSplitViewController


// The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization.
}
return self;
}
*/


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[super dealloc];
}


@end

和我的 DetailSplitViewController 的实现

#import "DetailSplitViewController.h"

@interface DetailSplitViewController ()
@property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
@end

@implementation DetailSplitViewController

@synthesize toolbar, popoverController, detailItem, detailDescriptionLabel;

/*
When setting the detail item, update the view and dismiss the popover controller if it's showing.
*/
- (void)setDetailItem:(id)newDetailItem {
if (detailItem != newDetailItem) {
    [detailItem release];
    detailItem = [newDetailItem retain];

    // Update the view.
    [self configureView];
}

if (self.popoverController != nil) {
    [self.popoverController dismissPopoverAnimated:YES];
}        
}

- (void)configureView {
// Update the user interface for the detail item.
// detailDescriptionLabel.text = [detailItem description];   
}

- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc 
{
barButtonItem.title = @"Root List";
NSMutableArray *items = [[toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = pc;
}

// Called when the view is shown again in the split view, invalidating the button and popover controller.
- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {

NSMutableArray *items = [[toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = nil;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
//[toolbar release];
[super dealloc];
} 

@end

Everiting 连接在 xib 中,我遇到的问题是,当我的 FirstSplitViewController 从 xib 加载时,我的主和详细 splitview 控制器没有分配(它们在 IB 中链接)。如果我手动分配它们,一切都会像魅力一样工作(在我的 FirstSplitViewController.m 中取消注释下面的 alloc init 行)

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

/*  
masterSplitViewController = [[[MasterSplitViewController alloc] initWithNibName:@"MasterSplitViewController" bundle:nil] autorelease];
detailSplitViewController = [[[DetailSplitViewController alloc] initWithNibName:@"DetailSplitViewController" bundle:nil] autorelease];
*/

self.viewControllers = [NSArray arrayWithObjects:masterSplitViewController, detailSplitViewController , nil];
self.delegate = detailSplitViewController;

}

所以我的问题是为什么当 xib 加载时这些对象没有加载?这确实是我第一次必须手动执行此操作。也许我错过了一些东西。

感谢您的任何答案或建议,

聪明

I'm currently playing with UISplitView Controller as I've got to have some of them working in a UITabBarController.
After a few tries, I've finally found a convenient way od doing it, the only issue I get is that I have to manually instanciate my detail and master view althought they are configured in IB and linked well.

Here is how I do it

I initialize a UITabBarCOntroller in my MainWindow.xib and set the tabbar items.

My first tab controller inherits from UISplitViewController and is set up with a xib.
Here is the implementation of this FirstViewController class

#import "FirstSplitViewController.h"
#import "MasterSplitViewController.h"
#import "DetailSplitViewController.h"


@implementation FirstSplitViewController

@synthesize detailSplitViewController,masterSplitViewController;



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

/*  
masterSplitViewController = [[[MasterSplitViewController alloc] initWithNibName:@"MasterSplitViewController" bundle:nil] autorelease];
detailSplitViewController = [[[DetailSplitViewController alloc] initWithNibName:@"DetailSplitViewController" bundle:nil] autorelease];
*/

self.viewControllers = [NSArray arrayWithObjects:masterSplitViewController, detailSplitViewController , nil];
self.delegate = detailSplitViewController;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[super dealloc];
}


@end

Here is my MasterSplitview Implementation

#import "MasterSplitViewController.h"


@implementation MasterSplitViewController


// The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization.
}
return self;
}
*/


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[super dealloc];
}


@end

and my DetailSplitViewController's implementation

#import "DetailSplitViewController.h"

@interface DetailSplitViewController ()
@property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
@end

@implementation DetailSplitViewController

@synthesize toolbar, popoverController, detailItem, detailDescriptionLabel;

/*
When setting the detail item, update the view and dismiss the popover controller if it's showing.
*/
- (void)setDetailItem:(id)newDetailItem {
if (detailItem != newDetailItem) {
    [detailItem release];
    detailItem = [newDetailItem retain];

    // Update the view.
    [self configureView];
}

if (self.popoverController != nil) {
    [self.popoverController dismissPopoverAnimated:YES];
}        
}

- (void)configureView {
// Update the user interface for the detail item.
// detailDescriptionLabel.text = [detailItem description];   
}

- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc 
{
barButtonItem.title = @"Root List";
NSMutableArray *items = [[toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = pc;
}

// Called when the view is shown again in the split view, invalidating the button and popover controller.
- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {

NSMutableArray *items = [[toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = nil;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
//[toolbar release];
[super dealloc];
} 

@end

Everiting is hooked up in xib's, and the problem I get is that when my FirstSplitViewController is loaded from it's xib, my master and detail splitview controllers aren't allocated (they are linked in IB). If I alloc them manually, everything works like a charm (uncommenting alloc init lines below in my FirstSplitViewController.m)

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

/*  
masterSplitViewController = [[[MasterSplitViewController alloc] initWithNibName:@"MasterSplitViewController" bundle:nil] autorelease];
detailSplitViewController = [[[DetailSplitViewController alloc] initWithNibName:@"DetailSplitViewController" bundle:nil] autorelease];
*/

self.viewControllers = [NSArray arrayWithObjects:masterSplitViewController, detailSplitViewController , nil];
self.delegate = detailSplitViewController;

}

So my question is why those objects are't loaded when the xib is? This is really the first time I have to do this manually. Maybe I'm missing something.

Thanks for any answers or advice

s-mart

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萧瑟寒风 2024-10-23 09:01:58

我刚刚遇到过同样的现象(我认为)。我刚刚开始完全理解 Interface Builder/控制器层次结构/视图层次结构在 iOS 上的工作方式。看起来通过 IBOutlet 链接的成员变量在访问控制器实例之前并未初始化。我的代码是这样的:

    if(self.sectionOneViewController == nil)
{
    SectionOneViewController *sectionOneView = [[SectionOneViewController alloc]
                        initWithNibName:@"SectionOne"
                        bundle:[NSBundle mainBundle]];
    self.sectionOneViewController = sectionOneView;

    [sectionOneView release];
    //[self showSectionOne:sender];
}

    [self.navigationController pushViewController:self.sectionOneViewController animated:YES];

[[UIApplication sharedApplication].keyWindow  addSubview:self.sectionOneViewController.sectionOneTabController.view];

如果我交换了最后两行的位置,除非我重新访问视图,否则sectionOneTabController将有一个零指针。我认为在访问 .xib 引用之前,有必要让控制器添加您的视图。

I've just run across this same phenomenon (I think). I'm just beginning to fully understand the way that Interface Builder/controller heirarchy/view heirarchy works for iOS. It looks like the member variables that are linked via IBOutlet are not initialized until the controller instance is accessed. My code was thus:

    if(self.sectionOneViewController == nil)
{
    SectionOneViewController *sectionOneView = [[SectionOneViewController alloc]
                        initWithNibName:@"SectionOne"
                        bundle:[NSBundle mainBundle]];
    self.sectionOneViewController = sectionOneView;

    [sectionOneView release];
    //[self showSectionOne:sender];
}

    [self.navigationController pushViewController:self.sectionOneViewController animated:YES];

[[UIApplication sharedApplication].keyWindow  addSubview:self.sectionOneViewController.sectionOneTabController.view];

if I swapped the location of the last 2 lines it would have a nil pointer for the sectionOneTabController unless I revisited the view. I think having a controller add your view is necessary before the .xib references can be accessed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文