1

カスタムuiview(MyCustomView)がNIB(MyCustomView.xib)からビューをロードする際に問題が発生しました。

問題は、MyCustomViewが他のXIBで再利用されるため、awakeFromNibが呼び出されることです。CustomView.xibにはMyCustomViewのインスタンスも含まれているため、MyCustomView.awakeFromNibのloadNibNamedは無限ループに入ります

imは次のように無限ループを取得します:

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/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;
}

CustomViewをインスタンス化するためにどこかでinitWithFrameを呼び出すことを前提としていることを除いて、これは問題ありません。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を呼び出すことです。

そこで、initWithFrameをロードするnibをsetupViewというメ​​ソッドに移動し、initWithFrameANDawakeFromNibから呼び出しました。

- (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ではScreenMenuButtonsViewawakeFromNibを呼び出すためです。

しかし、ここでは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

VIEWを変更する必要があります:UIView

しかし、ボタンのアウトレットとアクションはどうですか:ファイル所有者を変更する必要があります:設定されていないNSObject

ビュークラスになる

ファイル所有者:ScreenMenuButtonsView

4

0 に答える 0