6

I created a custom UICollectionViewCell containing an outlet for a label (placed in the Storyboard). I'd like to get the height of this label from within the awakeFromNib method of my custom UICollectionViewCell, but the size of the label is always 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

Console output:

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

How can I get the size of my label ? Is it too soon to get such information when awakeFromNib is called ? If so in which method of my custom cell should I get the size ?

EDIT

Here is the same strange behavior observed in the ViewController:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCustomCell" forIndexPath:indexPath];
    NSLog(@"%@", cell);
    NSLog(@"%@", cell.myLabel);
}

And the output:

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>>
Guillaume Algis
  • 10,705
  • 6
  • 44
  • 72
  • 1
    Documentation says that: _“When an object receives an `awakeFromNib` message, it is guaranteed to have all its outlet and action connections already established.”_ Make sure you have connected outlet. Try logging those two in `prepareForReuse` or other methods. If they are still zero, problem is somewhere else. – Tricertops Feb 06 '13 at 13:55
  • The value is correct when logged in `prepareForReuse`, but this is far too late for what I intend to do with this value. I'd like to draw a line using the height of my label, and this line should be visible (and correctly placed) when the cell is created. – Guillaume Algis Feb 07 '13 at 10:13
  • And what about `self.myLabel`? Is this outlet already set in this `-awakeFromNib`? – Tricertops Feb 07 '13 at 14:47
  • I edited the question, see first line of the console output – Guillaume Algis Feb 07 '13 at 15:05
  • 1
    I saw this behavior only once: `textLabel` of `UITableViewCell` has zero frame until the cell is displayed. But since this is `UICollectionViewCell` and the label is created by you in XIB, I really don't know why it has no frame. – Tricertops Feb 07 '13 at 15:49

2 Answers2

17

A part of the answer is in dreamzor's response to iOS AutoLayout - get frame size width.

The trick is to place your frame-dependent code to the viewDidLayoutSubviews method

In my particular case, I found that adding [self layoutIfNeeded]; in my custom cell awakeFromNib method, right before asking for the outlet size worked like a charm.

Community
  • 1
  • 1
Guillaume Algis
  • 10,705
  • 6
  • 44
  • 72
  • Can I give you more than a +1??? I was having trouble setting the layer corner radius. I wanted a round shaped UIButton and I was using self.layer setCornerRadius:self.bounds.size.width/2.0] but it was looking awful until I used your trick of adding [self layouIfNeeded] just before that. Thank you! – static0886 Jan 23 '16 at 07:32
-1

I am not sure if this is the optimal solution but to make some changes on subviews or getting information like you do, I create a method on the subview like "prepareSubviews" or "refresh" or "populateWithData". After initializing/ loading view from IB, I invoke that method inside "viewDidLoad", at that point the xib file should be loaded and working properly.

Yunus Nedim Mehel
  • 12,089
  • 4
  • 50
  • 56