在 awakeFromNib 中获取出口尺寸

Posted

技术标签:

【中文标题】在 awakeFromNib 中获取出口尺寸【英文标题】:Get outlet size within awakeFromNib 【发布时间】:2013-02-06 10:31:34 【问题描述】:

我创建了一个自定义UICollectionViewCell,其中包含一个标签出口(放置在情节提要中)。我想从自定义UICollectionViewCellawakeFromNib 方法中获取此标签的高度,但标签的大小始终为0.000000

// .h
@interface MyCustomCell : UICollectionViewCell

@property (weak, nonatomic) IBOutlet UILabel *myLabel;

@end

// .m
@implementation MyCustomCell

-(void)awakeFromNib

    [super awakeFromNib];

    NSLog(@"%@", self.myLabel);
    NSLog(@"%f", self.myLabel.frame.size.width);
    NSLog(@"%f", self.myLabel.frame.size.height);


@end

控制台输出:

2013-02-06 11:13:59.628 Test[8880:c07] <UILabel: 0x7649a00; frame = (0 0; 0 0); text = '12h00'; clipsToBounds = YES; opaque = NO; autoresize = TM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7649ac0>>
2013-02-06 11:13:59.628 Test[8880:c07] 0.000000
2013-02-06 11:13:59.630 Test[8880:c07] 0.000000

如何获得标签的尺寸? 调用awakeFromNib 时获得此类信息是否为时过早?如果是这样,我应该通过我的自定义单元格的哪种方法获得大小?

编辑

这是在 ViewController 中观察到的同样奇怪的行为:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

    MyCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCustomCell" forIndexPath:indexPath];
    NSLog(@"%@", cell);
    NSLog(@"%@", cell.myLabel);

还有输出:

2013-02-07 16:07:34.488 Test[30308:c07] <MyCustomCell: 0x7156980; baseClass = UICollectionViewCell; frame = (20 0; 290 655); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x7156a80>>
2013-02-07 16:07:34.489 Test[30308:c07] <UILabel: 0x7158100; frame = (0 0; 0 0); text = 'this is a text'; clipsToBounds = YES; opaque = NO; autoresize = TM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7158040>>

【问题讨论】:

文档说:“当一个对象收到awakeFromNib 消息时,它保证已经建立了它的所有出口和动作连接。” 确保你已经连接出口。尝试在prepareForReuse 或其他方法中记录这两个。如果它们仍然为零,则问题出在其他地方。 登录 prepareForReuse 时该值是正确的,但这对于我打算使用此值执行的操作来说为时已晚。我想用标签的高度画一条线,这条线在创建单元格时应该是可见的(并且放置正确)。 那么self.myLabel 呢?这个插座已经设置在这个-awakeFromNib吗? 我编辑了问题,见控制台输出的第一行 我只看到过一次这种行为:UITableViewCelltextLabel 在显示单元格之前为零帧。不过既然是UICollectionViewCell,而且标签是你在XIB中创建的,我真不知道为什么它没有框架。 【参考方案1】:

部分答案在dreamzor 对ios AutoLayout - get frame size width 的回复中。

诀窍是将依赖于帧的代码放置到 viewDidLayoutSubviews 方法中

在我的特殊情况下,我发现在我的自定义单元格 awakeFromNib 方法中添加 [self layoutIfNeeded];,就在询问插座尺寸之前就像一个魅力。

【讨论】:

我可以给你超过+1吗???我在设置图层角半径时遇到问题。我想要一个圆形的 UIButton 并且我正在使用 self.layer setCornerRadius:self.bounds.size.width/2.0] 但它看起来很糟糕,直到我使用你之前添加 [self layouIfNeeded] 的技巧。谢谢!【参考方案2】:

我不确定这是否是最佳解决方案,但为了对子视图进行一些更改或像您一样获取信息,我在子视图上创建了一个方法,如“prepareSubviews”或“refresh”或“populateWithData”。从 IB 初始化/加载视图后,我在“viewDidLoad”中调用该方法,此时应该加载 xib 文件并正常工作。

【讨论】:

XIB 应该在awakeFromNib 处完全加载,所以我认为问题出在其他地方。

以上是关于在 awakeFromNib 中获取出口尺寸的主要内容,如果未能解决你的问题,请参考以下文章

为啥在使用情节提要时反复调用 AwakeFromNib?

如何在同一类的 awakeFromNib 方法中获取当前视图控制器?

awakeFromNib 无法从 UILabel 获取值,也无法禁用 UIButton

awakeFromNib 返回 Null UILabel 值

如何获得从 awakeFromNib 到 mainViewController.m 的对象高度?

在 awakeFromNib 中添加子视图