2016-08-24 57 views
0

我從xib中創建了一個名爲HeaderView的自定義UIView。我在這個HeaderView和按鈕水龍頭中有一個UIButton,我想要在添加HeaderView的ViewController上調用一個塊。這是我的HeaderView的代碼。目標C塊變爲無

頭文件中的代碼

@interface HeaderView : UIView 

- (instancetype)initWithFrame:(CGRect)frame; 

@property (copy) void(^seeAllHandler)(); 

@end 

執行文件中的代碼

@interface HeaderView() 

@property (weak, nonatomic) IBOutlet UILabel *titleLabel; 
@property (weak, nonatomic) IBOutlet UIButton *seeAllButton; 
@property (nonatomic, strong) UIView *contentView; 

@end 

@implementation HeaderView 


- (instancetype)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self setup]; 
    } 
    return self; 
} 

- (instancetype)initWithCoder:(NSCoder *)coder 
{ 
    self = [super initWithCoder:coder]; 
    if (self) { 

    } 
    return self; 
} 

- (void)awakeFromNib 
{ 
    [self.seeAllButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 
    [self.seeAllButton setTitle:@"SEE ALL") forState:UIControlStateNormal]; 
    [self.titleLabel setText:@"My Label")]; 

} 

#pragma mark - Private methods 

- (void)setup 
{ 
    //Setup view from the xib file. 
    self.contentView = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil] firstObject]; 
    [self.contentView setFrame:self.bounds]; 
    [self addSubview:self.contentView]; 
    self.contentView.backgroundColor = [UIColor ccNordeaPink]; 
    self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    self.clipsToBounds = YES; 
} 

- (IBAction)sellAllTapped:(UIButton *)sender { 
    if(self.seeAllHandler != nil){ 
     self.seeAllHandler(); 
    } 

} 

@end 

,這裏是我的視圖控制器viewDidLoad方法。

@interface ViewController() <UIScrollViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate> 

@property (nonatomic, strong) HeaderView *headerView; 

@end 



- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self setupSubviews]; 
    [self setupConstraints]; 

} 

- (void)setupSubviews 
{ 

    self.headerView = [[HeaderView alloc] init ]; 
    self.headerView.translatesAutoresizingMaskIntoConstraints = NO; 

    self.headerView.seeAllHandler = ^{ 
     DDLogDebug(@"See all Tapped"); 
    }; 

[self.view addSubView: self.headerView]; 


} 

問題是,當點擊按鈕時,分配的塊是零,因此它不會被調用。

回答

2

所以發生了什麼是你正在ViewController的viewDidLoad(通過setupSubviews方法)分配塊。我可以看到你正在編程實例化一個HeaderView。所以當你分配塊時,你實際上是在向實例發送消息。

但是,您也在通過在HeaderView的setup方法內調用loadNibNamed來擴充另一個實例。 HeaderView沒有你的區塊,這是在UI中顯示的區塊。你在HeaderView的contentView裏有另一個HeaderView。

因此,實際/屏幕上的 HeaderView實例的處理程序屬性爲零,所以當它試圖將該塊觸發回給它時,它也與nil一起工作。

處理髮生的事情的最好方法是進入HeaderView並在awakeFromNib中設置一個斷點,並在setup中設置另一個斷點。你會看到安裝程序首先被調用。如果你在lldb中使用po self,你會得到當前實例的地址。接下來發生的事情是awakeFromNib被調用並且它在那裏觸發了斷點。如果您再次執行po self,則會看到不同的地址。一個不同的實例!這是你在UI中看到的那個。它沒有處理程序集!

如果你想保持這種加載視圖層次結構的方法,那麼一個簡單的修復就是在你的ViewController中從nib實例化HeaderView。

因此,而不是做self.headerView = [[HeaderView alloc] init]的,你這樣做:

 
self.headerView = [[[NSBundle mainBundle] loadNibNamed:@"HeaderView" owner:self options:nil] firstObject]; 
+0

感謝很好解釋。 – Madu