1

我有一个自定义 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

4

0 回答 0