我有一个自定义 uiview (MyCustomView) 从 NIB (MyCustomView.xib) 加载其视图的问题。
问题是 MyCustomView 在其他 XIB 中被重用,所以 awakeFromNib 被调用。CustomView.xib 还包含 MyCustomView 的一个实例,因此 MyCustomView.awakeFromNib 中的 loadNibNamed 进入无限循环
我得到无限循环:
SomeVC.xib
+ calls MyCustomView awakeFromNib
++ which calls loadNibNamed: MyCustomView.nib
+++++ but top level View is also instance of MyCustomView
....so awakeFromNib: goes into infinite loop
我只是想知道当自定义视图从笔尖加载其自身时,顶级 UIView 是否不应该是 MyCustomView 的实例?如果是这样,我如何连接插座/操作(我是否让 MyCustomView 成为文件所有者?)
无论如何欢呼
LONG EXPLANATION:
我有一排按钮,我想在多个屏幕上重复使用。所以我创建了一个自定义视图
@interface ScreenMenuButtonsView : UIView
@property (retain, nonatomic) IBOutlet UIButton *buttonHome;
@property (retain, nonatomic) IBOutlet UIButton *buttonMyMusic;
@property (retain, nonatomic) IBOutlet UIButton *buttonStore;
@property (retain, nonatomic) IBOutlet UIButton *buttonSocial;
@property (retain, nonatomic) IBOutlet UIButton *buttonSettings;
@end
我想在 IB 中布局视图,所以我创建了一个 NIB
ScreenMenuButtonsView_iPad.xib
Files Owner: no set NSObject
VIEW: ScreenMenuButtonsView
+ UIButton
+ UIButton
+ UIButton
我希望自定义视图在内部加载自己的 NIB,我使用了 http://nathanhjones.com/2011/02/20/creating-reusable-uiviews-with-a-drop-shadow-tutorial/ http://nathanhjones.com/2011/02/20/creating-reusable-uiviews-with-a-drop-shadow-tutorial/ http:// /nathanhjones.com/wp-content/uploads/2011/02/ReusableTableHeaders.zip
- (id)initWithFrame:(CGRect)frame {
//self = [super initWithFrame:frame]; // not needed - thanks ddickison
if (self) {
NSArray *nib = [[NSBundle mainBundle]
loadNibNamed:@"HeaderView"
owner:self
options:nil];
[self release]; // release object before reassignment to avoid leak - thanks ddickison
self = [nib objectAtIndex:0];
self.layer.shadowColor = [[UIColor blackColor] CGColor];
self.layer.shadowOffset = CGSizeMake(1.0, 1.0);
self.layer.shadowOpacity = 0.40;
}
return self;
}
没关系,除非这假定您在某处调用 initWithFrame 来实例化 CustomView。HeaderView 示例这样称呼它:
// load the header - this could be done in viewWillAppear as well
HeaderView *header = [[HeaderView alloc]
initWithFrame:CGRectMake(0, 0, 320, 60)];
header.lblTitle.text = @"That. Just. Happened.";
tblData.tableHeaderView = header;
[header release];
我希望能够在任何其他 XIB 中使用我的自定义视图类
HomeScreenViewController.xib
Files Owner: HomeScreenViewController
View:
+ ....other controls
+ ScreenMenuButtonsView
问题是加载 HomeScreenViewController 时,它会在我的 customView 上调用 awakeFromNib:
所以我将 nib 加载出 initWithFrame 并移到一个名为 setupView 的方法中,并从 initWithFrame 和 awakeFromNib 调用它
- (id) initWithFrame:(CGRect)frame
{
if ( ( self = [super initWithFrame: frame] ) )
{
[self setUpView];
}
return self;
}
- (void)awakeFromNib
{
[self setUpView];
}
- (void) setUpView{
if (self) {
NSArray* nibViewsArray = nil;
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
//IPAD
nibViewsArray = [[NSBundle mainBundle] loadNibNamed:@"ScreenMenuButtonsView_iPad"
owner:self
options:nil];
...
}
我的问题是加载 HomeScreenViewController.xib 时:
HomeScreenViewController.xib
Files Owner: HomeScreenViewController
View:
+ ....other controls
+ ScreenMenuButtonsView
它尝试创建 ScreenMenuButtonsView 并且因为它在 NIB 中它调用 ScreenMenuButtonsView awakeFromNib
但是在这里我称之为 loadNibNamed:
- (void) setUpView{
_viewSetupAlready = TRUE;
//http://nathanhjones.com/2011/02/20/creating-reusable-uiviews-with-a-drop-shadow-tutorial/
//self = [super initWithFrame:frame]; // not needed - thanks ddickison
if (self) {
NSArray* nibViewsArray = nil;
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
//IPAD
nibViewsArray = [[NSBundle mainBundle] loadNibNamed:@"ScreenMenuButtonsView_iPad"
owner:self
options:nil];
}else{
//IPHONE
nibViewsArray = [[NSBundle mainBundle] loadNibNamed:@"ScreenMenuButtonsView_iPhone"
owner:self
options:nil];
}
if(nibViewsArray){
//[self release]; // release object before reassignment to avoid leak - thanks ddickison
UIView * myView = [nibViewsArray objectAtIndex: 0];
//Check the top level object in NIB is same type as this custom class
//if wrong you probably forgot to use correct NIB name in loadNibNamed:
if([myView isMemberOfClass:[self class]]){
self = (ScreenMenuButtonsView *)myView;
}else{
NSLog(@"ERROR:top level view is not same type as custom class - are you loading the correct nib filename in loadNibNamed:\n%@", myView);
}
}else{
NSLog(@"ERROR:nibViewsArray is nil");
}
}
}
loadNibName: 加载
ScreenMenuButtonsView_iPad.xib
Files Owner: no set NSObject
VIEW: ScreenMenuButtonsView
+ UIButton
+ UIButton
+ UIButton
但是顶视图是 ScreenMenuButtonsView 所以创建一个新实例并调用 awakeFromNib 并且我得到无限循环。
我知道为什么会发生循环并且 ScreenMenuButtonsView 上的实例正在从 xib 加载另一个实例。
我的问题在
ScreenMenuButtonsView_iPad.xib
Files Owner: no set NSObject
VIEW: ScreenMenuButtonsView
+ UIButton
+ UIButton
+ UIButton
我应该改变视图:UIView
但是按钮的出口和操作呢:我应该更改文件所有者:没有设置 NSObject
成为视图类
文件所有者:ScreenMenuButtonsView