ios - UITableViewCell Autolayout for Different Widths -


i've setup uitableviewcell in storyboard has 2 labels, setup so:

----------------------- | ------------------- | | |     label 1     | | | ------------------- | | ------------------- | | |     label 2     | | | ------------------- | ----------------------- 
  • label 1 has fixed 15px constraints top, left , right margins. content hugging (h: 251, v: 251). compression resistance (h: 750, v: 750).
  • label 2 has fixed 15px constraints bottom, left , right margins. content hugging (h: 251, v: 251). compression resistance (h: 750, v: 751).
  • label 1 has fixed 1px constraint label 2.

the height of cell calculated follows:

- (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath {     int width = tableview.bounds.size.width - 30;      nsstring *label1text = ....;     nsstring *label2text = ....;      int label1height = ceilf([label1text boundingrectwithsize:cgsizemake(width, maxfloat) options:nsstringdrawinguseslinefragmentorigin attributes:@{nsfontattributename:[uifont systemfontofsize:17.0]} context:nil].size.height);     int label1height = ceilf([label2text boundingrectwithsize:cgsizemake(width, maxfloat) options:nsstringdrawinguseslinefragmentorigin attributes:@{nsfontattributename:[uifont systemfontofsize:17.0]} context:nil].size.height);      return 15 + label1height + 1 + label2text + 15; } 

this works great width of storyboard template (e.g. 320px). when uitableviewcontroller view width made bigger (e.g. 500px+), cell adopts correct height, however, label 1 becomes big content (spanning 1 line of text on 2 lines) , label 2 becomes squashed (spanning 2 lines of text 1 line).

however, if resize uitableviewcontroller in storyboard (e.g. 500px wide) , update frames of labels (maintaining same constraints), when view loaded looks perfect @ 500px wide , terrible @ 320px wide.

can (who has more knowledge of autolayout) please explain this?

i'm making assumption intend have multiple lines of text each label. uilabels need know how wide will before can give accurate height when returns intrinsic content size. intended behavior can accomplished setting preferredmaxlayoutwidth, may have obvious limitation: whole point of using auto layout don't need or want know exact values be.

you can either manually calculate (if it's not fixed value) want label @ point. clunky solution me.

i prefer create uilabel subclass merely overrides layoutsubviews can automatically configure preferredmaxlayoutwidth when being laid out.

// ebtsmartwidthlabel.h  #import <uikit/uikit.h>  @interface ebtsmartwidthlabel : uilabel  @end 

and then

// ebtsmartwidthlabel.m  #import "ebtsmartwidthlabel.h"  @implementation ebtsmartwidthlabel  - (void)layoutsubviews {     self.preferredmaxlayoutwidth = 0.0f;     [super layoutsubviews];     self.preferredmaxlayoutwidth = cgrectgetwidth(self.bounds);     [super layoutsubviews]; }  @end 

the code first sets preferredmaxlayoutwidth 0.0f, makes uilabel wide possible. performs actual layout, , width constricted auto layout constraints. takes width (which should widest (in case)) , makes preferredmaxlayoutwidth , performs layout again.

this isn't efficient way , in rare/complex/contrived situations, may lead lots of re-layouts, i've had great results it.

if you're using storyboard/interface bulder, can set custom class on uilabel, allow use custom class.

custom class in interface builder


Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -