2016-08-24 34 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