2016-08-24 3 views
0

Я создаю пользовательский UIView из xib под названием HeaderView. У меня есть UIButton в этом HeaderView и при нажатии кнопки, я хочу, чтобы блок был вызван в ViewController, в который добавляется HeaderView. Вот код для моего HeaderView.Объективный блок C становится Nil

Заголовок файла кода Code

@interface HeaderView : UIView 

- (instancetype)initWithFrame:(CGRect)frame; 

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

@end 

Реализация File

@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 

и вот мой метод ViewController 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

Так что происходит то, что вы назначаете блок в viewDidLoad (через метод setupSubviews) ViewController. Я вижу, что вы программно создаете экземпляр HeaderView. Поэтому, когда вы назначаете блок, вы фактически отправляете сообщение экземпляру.

Но вы также раздуваете другой экземпляр, вызывая loadNibNamed внутри метода HeaderView setup. И , что HeaderView не имеет вашего блока, и это тот, который отображается в пользовательском интерфейсе. У вас есть еще один HeaderView внутри contentView вашего HeaderView.

Следовательно, актуально/на экране Свойство обработчика экземпляра HeaderView равно нулю, поэтому, когда он пытается запустить блок обратно к вам, он также работает с nil.

Лучший способ приблизиться к тому, что происходит, - перейти в HeaderView и установить точку останова в awakeFromNib и другую точку останова в setup. Вы увидите, что настройка сначала вызвана. Если у вас po self в lldb, вы укажете адрес текущего экземпляра. Следующее, что происходит, это то, что awakeFromNib вызывается, и он попадает в точку останова. И если вы снова сделаете po self, вы увидите другой адрес. Другой пример! Это тот, который вы видите в пользовательском интерфейсе. И у него нет набора обработчиков!

Если вы хотите сохранить эту методологию для загрузки иерархии представлений, тогда простое исправление заключается в создании экземпляра HeaderView из nib внутри вашего ViewController.

Таким образом, вместо того, чтобы делать self.headerView = [[HeaderView alloc] init], вы делаете это:

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

Благодаря очень хорошо объяснимые. – Madu

Смежные вопросы