2014-11-21 63 views
5

我絕望地卡住了,我將不勝感激一個指針。自定義UIView子類需要awakeFromNIB被調用兩次

我們試圖構建一個包含多個視圖的視圖控制器,這些視圖是UIView的一個子類。除了我們需要手動初始化視圖或再次手動調用awakeFromNib(這是不允許的)之外,所有的工作都「很好」。

這裏的問題是...

子類的UIView頭文件:

#import <UIKit/UIKit.h> 
@interface introView : UIView 
@property (strong, nonatomic) UIView *view; 
@property (strong, nonatomic) NSString *title; 
@property (strong, nonatomic) IBOutlet UILabel *titleLabel; 
@end 

子類的UIView主文件:

#import "introView.h" 

@interface introView() 
@end 

@implementation introView 

-(id)init 
{ 
    NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"introView" owner:self options:nil]; 
    id mainView = [subviewArray objectAtIndex:0]; 
    return mainView; 
} 
- (void) awakeFromNib 
{ 
    [super awakeFromNib]; 
    [self initialize]; 
    [self addSubview:self.view]; 
} 

-(void)initialize 
{ 
    NSLog(@"title: %@", self.title); 
    self.titleLabel.text = self.title; 
} 

然後我們從一個視圖控制器這樣做初始化視圖:

introView *view = [[introView alloc]init]; 
view.title = @"Test"; 
[self addSubview:view]; 

這裏是問題 - 通過調用這個視圖,視圖正確顯示,但標題爲NULL;

[43605:1957090] title: (null) 

然而,如果我們調用awakeFromNib再次,那麼該觀點正確

初始化在視圖控制器:

introView *view = [[introView alloc]init]; 
view.title = @"Test; 
[self addSubview:view]; 
[view awakeFromNib]; 

然後,它的工作原理:

2014-11-21 09:33:03.500 Test[43706:1972060] title: (null) 
2014-11-21 09:33:03.500 Test[43706:1972060] title: Test 

或者,如果我做初始化方法public並在初始化之後調用它以及。但是,這違背了我眼中的目的...

在視圖控制器:

introView *view = [[introView alloc]init]; 
view.title = @"Test; 
[self addSubview:view]; 
[view initialize]; //calling the method directly... 

看來我,我們在某種程度上運行到哪裏的觀點還沒有準備好條件,但隨後在工作第二次嘗試(即使awakeFromNib調用是非法的)

再次,插座設置正確,文件所有者被設置...它只需要兩個awakeFromNib調用。

任何幫助表示讚賞。

---------------- UPDATE ------------------

謝謝你們,我欣賞指針。我按照概述實現了初始化程序,但是我遇到了同樣的問題。此外,我使用GitHub示例作爲一個乾淨的示例,並試圖爲此視圖分配一個變量,甚至顯示相同的行爲。因此我開始認爲我在其他地方做錯了事。看到這裏:

// 
// SubClassView.h 
// CustomView 
// 
// Created by Paul Solt on 4/28/14. 
// Copyright (c) 2014 Paul Solt. All rights reserved. 
// 

#import <UIKit/UIKit.h> 
#import "PSCustomViewFromXib.h" 

@interface SubClassView : PSCustomViewFromXib 
@property (strong, nonatomic) NSString *title; 
@end 

SubclassView。米

// 
// SubClassView.m 
// CustomView 
// 
// Created by Paul Solt on 4/28/14. 
// Copyright (c) 2014 Paul Solt. All rights reserved. 
// 

#import "SubClassView.h" 

@interface SubClassView() 
@property (weak, nonatomic) IBOutlet UILabel *label; 
@property (weak, nonatomic) IBOutlet UISwitch *onSwitch; 


@end 

@implementation SubClassView 

// Note: You can customize the behavior after calling the super method 

// Called when loading programatically 
- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if(self) { 
     // Call a common method to setup gesture and state of UIView 
     [self setup]; 
    } 
    return self; 
} 

// Called when loading from embedded .xib UIView 
- (id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super initWithCoder:aDecoder]; 
    if(self) { 
     // Call a common method to setup gesture and state of UIView 
     [self setup]; 
    } 
    return self; 
} 

- (void)setup { 
    // Add a gesture to show that touch input works on full bounds of UIView 
    NSLog(@"%@", self.title); 
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; 
    [self addGestureRecognizer:panGesture]; 
} 

- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture { 
    NSLog(@"Pan: %@", NSStringFromCGPoint([gesture locationInView:gesture.view])); 
} 
- (IBAction)switchChanged:(UISwitch *)sender { 
    NSLog(@"Switch: %d", sender.on); 
} 

@end 

視圖控制器類

// 
// ViewController.m 
// CustomView 
// 
// Created by Paul Solt on 4/28/14. 
// Copyright (c) 2014 Paul Solt. All rights reserved. 
// 

#import "ViewController.h" 
#import "SubClassView.h" 
#import "LabelMadness.h" 

@interface ViewController() 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 


    // Add a custom view's programmatically (position using 1/2 width and height) 

    SubClassView *oneView = [[SubClassView alloc] init]; 
    oneView.center = CGPointMake(80 + 80, 282 + 40); 
    oneView.backgroundColor = [UIColor blueColor]; 
    oneView.title = @"Test2"; 
    [self.view addSubview:oneView]; 

} 

@end 

-------輸出-----

2014-11-21 11:49:38.893 CustomView[45653:2123668] LabelMadness.initWithFrame: 
2014-11-21 11:49:38.893 CustomView[45653:2123668] (null) 

我在做什麼錯在這裏?

+0

你的代碼有點混亂。在introView類中,什麼是self.view(在[self addSubview:self.view]中)? mainView的外觀是什麼(它有哪些子視圖)? – rdelmar 2014-11-21 18:38:18

回答

2

你不需要完全可以使用awakeFromNib。如果你想introView加載自己的筆尖,你能做到這一點,像這樣(更改類在廈門國際銀行文件的視圖到introView的),

-(instancetype)init{ 
    if (self = [super init]) { 
     NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"introView" owner:self options:nil]; 
     self = [subviewArray objectAtIndex:0]; 
    } 
    return self; 
} 

設置標題,您可以覆蓋的二傳手你title property,

-(void)setTitle:(NSString *)title { 
    _title = title; 
    self.titleLabel.text = title; 
} 

控制器中的代碼與您最初嘗試的代碼相同。

+0

我試過,但後來我得到一個異常... ***終止應用程序由於未捕獲的異常'NSInvalidArgumentException',原因:' - [UIView setTitle:]:無法識別的選擇發送到實例0x7fbc4d8c4040' – user3757285 2014-11-21 20:11:22

+0

@ user3757285,這聽起來像你沒有改變你的xib中的視圖類到你的自定義類(這就是爲什麼錯誤說UIView不introView)。 – rdelmar 2014-11-21 20:47:26

+0

你是對的,它不正確,但它不會改變任何東西。我得到一個異常。不過,我開始認爲我的整個方法有些缺陷。是不是可以將全局變量作爲init函數的一部分來分配?我是否必須調用[view initialize]來獲取變量?它對我來說沒有任何意義,但它的工作方式... – user3757285 2014-11-21 21:05:13

0

那麼,你有沒有在.xib或故事板中的觀點?

它看起來就像是從的.xib所以你應該看看this answer

你不應該重寫init方法,你不應該在代碼初始化的Alloc它。如果這樣做,則在界面構建器中製作的視圖將不會被加載。

因此,而不是alloc init,按照我指出的答案,並做類似的事情。

反正我看不出你在哪裏初始化的

@property (strong, nonatomic) UIView *view; 

是不是一個IBOutlet和你永遠不會在任何地方初始化它,所以顯然這將是永遠nil

相關問題