Laying Out Subviews


#1

I am having a wee bit of trouble understanding part of the layoutSubviews: method, in particular the width of the nameFrame.

So our math for this is:
w - (h + valueWidth + inset * 4.0)

which translates to
bounds.size.width - (43 (3G portrait mode) + 40 + 20)

What I don’t get is why the width of the space required by the nameFrame is calculated using the bounds.size.height. Why does the height of the cell need to be taken into consideration?

If I take out the h + part the value field moves off to the right of the UI.

I am probably being rather stupid here, however can someone explain please?

Cheers,
Nick
http://myfirstiphoneapp.co.uk


#2

IIRC, the imageView on the left of the cell is h points wide (to make it a square). Or maybe a bit smaller.

This math figures out the position and size of the fixed elements (imageView, valueLabel) and uses the remaining space to determine the size of the nameLabel.


#3

Oh yeah, I realise nameFrame uses the position and size of the other elements to position and size itself, I just don’t see why the math is made up using “h”, and not thumbnailSize.width.


#4

I had the same confusion. Subtracting a height from a width just didn’t make sense. (And it still doesn’t.)

To get a better visualization on what the code is trying to do, I added a background colour to each item:

    [imageView setFrame: imageFrame];
    [imageView setBackgroundColor: [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.1]];
...
    [nameLabel setFrame: nameFrame];
    [nameLabel setBackgroundColor: [UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:0.1]];
...
    [valueLabel setFrame: valueFrame];
    [valueLabel setBackgroundColor: [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:0.1]];

The imageFrame and the valueFrame both have constant widths (40 pixels each). The nameFrame’s width should be whatever is left after subtracting out both of those and all four insets (far left, far right, between image and name, and between name and value). That leaves us with:

    CGRect nameFrame = CGRectMake( imageFrame.size.width + imageFrame.origin.x + inset, 
                                  inset, 
                                  boundsWidth - (imageWidth + valueWidth + inset * 4.0), 
                                  boundsHeight - inset * 2.0
                                  );

(h and w are fine abbreviations for height and width when there’s only one, but we’re using so many widths here that I renamed those boundsHeight and boundsWidth respectively. I also defined imageWidth as 40 up with valueWidth 40, to make it clear the same width was being used both when creating imageFrame and when computing nameFrame.)


#5

To me, “w - (40.0 + valueWidth + inset * 4.0)” makes more sense.
(40.0 is the height of the imageView.)

But “w - (h + valueWidth + inset * 4.0)” works also (and is slightly more spacious) because h = inset + 40 + remaining height in cell under the imageView.
Is my understanding correct? Please correct me if I got it wrong. Thanks!


#6

The way I understood it, and correct me if I’m wrong, is that ‘h’ is roughly equivalent to imageFrame.size.width + inset. Since the imageView area is roughly a square, it’s h wide by h high, and it’s simply quicker to just use ‘h’ instead of having to type imageFrame.size.width + inset.