ios - How does UILabel vertically center its text? -
there has been lot of confusion trying achieve. please let me reword question. simple as:
how apple center text inside
uilabel
's-drawtextinrect:
?
here's context on why looking apple's approach center text:
- i not happy how center text inside method
- i have own algorithm job way want
however, there places can't inject algorithm into, not method swizzling. getting know exact algorithm use (or equivalent of that) solve personal problem.
here's demo project can experiment with. in case you're interested problem apple's implementation is, @ left side (base uilabel): text jumps , down increase font size using slider, instead of gradually moving downwards.
again, looking implementation of -drawtextinrect:
same base uilabel
-- without calling super
.
- (void)drawtextinrect:(cgrect)rect { cgrect const centeredrect = ...; [self.attributedtext drawinrect:centeredrect]; }
i don't have answer, did little research , thought i'd share it. used xtrace, lets trace objective-c method calls, try , figure out uilabel doing. added xtrace.h
, xtrace.mm
xtrace git repository christian's uilabel demo project. in rootviewcontroller.m
, added #import "xtrace.h"
, , experimented various trace filters. adding following rootviewcontroller's loadview
:
[xtrace includemethods:@"drawwithrect|drawinrect|drawtextinrect"]; [xtrace traceclasspattern:@"string|uilabel|applelabel" excluding:nil];
gives me output:
| [<applelabel 0x7fedf141b520> drawtextinrect:{{0, 0}, {187.5, 333.5}}] | [<nsconcretemutableattributedstring 0x7fedf160ec30>/nsattributedstring drawinrect:{{0, 156.5}, {187.5, 333.5}}] | [<uilabel 0x7fedf1418dc0> drawtextinrect:{{0, 0}, {187.5, 333.5}}] | [<uilabel 0x7fedf1418dc0> _drawtextinrect:{{0, 0}, {187.5, 333.5}} baselinecalculationonly:0] | [<__nscfconstantstring 0x1051d1db0>/nsstring drawwithrect:{{0, 156.3134765625}, {187.5, 20.287109375}} options:1l attributes:<__nsdictionarym 0x7fedf141ae00> context:<nsstringdrawingcontext 0x7fedf15503c0>]
(i'm running xcode 7.0 beta, ios 9.0 simulator.)
we can see apple's implementation not send drawinrect:
nsattributedstring, drawwithrect:options:attributes:
nsstring. i'm guessing these end doing same.
we can see calculated y offset is. in initial position of slider, 156.3134765625. interesting note not falls on rounded integer value, or multiple of 0.25 or similar, otherwise explanation jumpiness.
we see uilabel sends 20.287109375 height, same value calculated self.attributedtext.size.height
. seems using that, though haven't been able trace call (maybe using core text directly?).
so that's i'm stuck. been trying @ difference between uilabel calculates , obvious formula "labelyoffset = (boundsheight - labelheight) / 2.0", find no consistent pattern.
update 1. can model elusive y offset as
labelyoffset = (boundsheight - labelheight) / 2.0 + error
what error
is, we're trying figure out. let's try study scientist. here xtrace output when i've dragged slide end , beginning. added nslog @ each change of slider helps separating entries. wrote a python script plot error against label height.
interesting. see there's linearity errors, strangely jump between lines @ points, if understand mean. going on here? i'll losing sleep until solved. :)
Comments
Post a Comment