ios - Putting text in Circle as big as possible -


it´s pretty basic problem couldn´t find proper solution it. have several circles have text in can see in picture. text gets loaded dynamically , has size 1 word 5 words or more. goal put text big possible circle. new lines can appear every individual word should stay together. example image kind of ok prefer text bigger because there still free space between text , circle. circle 80x80. solution tried cropped text strangly or text small.

how create label:

uilabel *buttonlabel = [[uilabel alloc] initwithframe:cgrectmake(12,7,57,64)];      [buttonlabel settext: @"recipes"];     buttonlabel.font = [uifont fontwithname:@"helveticaneue-light" size:18.0f];     buttonlabel.textcolor = [uicolor whitecolor];     buttonlabel.textalignment = nstextalignmentcenter;     buttonlabel.linebreakmode = nslinebreakbywordwrapping;     buttonlabel.numberoflines = 3;    [button addsubview:buttonlabel];    [buttonlabel release]; 

enter image description here

edit: tried solution of rufel. think shrinking kind of works words ripped apart. though have buttonlabel.linebreakmode = nslinebreakbywordwrapping;

it looks this:

enter image description here

this code. implemented other methods mentioned in answer.

//create button labels     uilabel *buttonlabel = [[uilabel alloc] initwithframe:cgrectmake(0, 0, 60, 60)];       [buttonlabel settext: @"text";     buttonlabel.textcolor = [uicolor whitecolor];     buttonlabel.textalignment = nstextalignmentcenter;     buttonlabel.linebreakmode = nslinebreakbywordwrapping;      buttonlabel.numberoflines = 0;      cgfloat fontsize = 20; // max font size want use     cgfloat labelheightwithfont = 0;     uifont *labelfont = nil;      {         // trying current font size if fits         labelfont = [uifont systemfontofsize:fontsize--];         cgrect boundingrect = [self boundingrectforstring:subcatbuttontitlesarray[buttontag-1] font:labelfont];         labelheightwithfont = boundingrect.size.height;         // loop until text @ current size fits maximum width/height.     } while (labelheightwithfont > [self buttonlabelmaxwidth]);      buttonlabel.text = subcatbuttontitlesarray[buttontag-1];     buttonlabel.font = labelfont;  - (cgrect)boundingrectforstring:(nsstring *)string font:(uifont *)font  {  return [string boundingrectwithsize:cgsizemake([self buttonlabelmaxwidth], maxfloat)                                       options:nsstringdrawinguseslinefragmentorigin | nsstringdrawingusesfontleading                                    attributes:@{nsfontattributename: font}                                       context:nil];  }    - (cgfloat)buttonlabelmaxwidth       {    cgfloat hypotenuse = cgrectgetwidth(cgrectmake(0, 0, 60, 60));    cgfloat righttrianglecathetus = sqrtf((hypotenuse*hypotenuse)/2);    return righttrianglecathetus;       } 

i found thread here:

ios7 - adjusting font size of multiline label fit frame

which has same problem.

edit 2:

after searching complete day solution , trying kinds of combinations of label attributes somehow figured out "numberoflines" culprit. came dumb solution of counting words in string , adjust number of lines based on numbers of string:

    nsstring *samplestring = @"three words string"; //count words in string int times = [[samplestring componentsseparatedbystring:@" "] count]-1;  uilabel *testlabel = [[uilabel alloc]initwithframe:cgrectmake(30, 30, 60, 60)]; [testlabel settext:samplestring];    [testlabel setfont:[uifont fontwithname:@"helveticaneue-ultralight" size:40.0f]]; [testlabel setbackgroundcolor:[uicolor redcolor]];   [testlabel setadjustsfontsizetofitwidth:yes];   [testlabel settextalignment:nstextalignmentcenter];  //my workaround if(times ==0){ [testlabel setnumberoflines:1]; }else{     if(times==1){         [testlabel setnumberoflines:2];     }         else{             [testlabel setnumberoflines:3];         }}      [self.view addsubview:testlabel]; 

say have custom view in draw circle fits frame (80x80 in example).

you first want find maximum width label can take without letters crossing circle:

- (cgfloat)buttonlabelmaxwidth {     cgfloat hypotenuse = cgrectgetwidth(self.bounds);     cgfloat righttrianglecathetus = sqrtf((hypotenuse*hypotenuse)/2);     return floorf(righttrianglecathetus); } 

next, when pass title display, want iterate decreasing oversized font until resulting string boundary fits width calculated (which maximum height since it's circle). update: want check every words in title sure not being truncated (that fit maximum width).

- (void)setbuttontitle:(nsstring *)title {     cgfloat fontsize = 20; // max font size want use     cgfloat minimumfontsize = 5; // min font size want use     cgfloat labelheightwithfont = 0;     cgfloat longestwordwidth = 0;     uifont *labelfont = nil;      cgfloat buttonlabelmaxwidth = [self buttonlabelmaxwidth];      {          if (fontsize < minimumfontsize) {             // handle exception title won't fit             break;         }          // trying current font size if fits         labelfont = [uifont systemfontofsize:fontsize--];         cgsize boundingsize = [self boundingsizeforstring:title font:labelfont];         labelheightwithfont = boundingsize.height;          // sure words not truncated (that fits in maximum width)         longestwordwidth = 0;         (nsstring *word in [title componentsseparatedbycharactersinset:[nscharacterset whitespaceandnewlinecharacterset]]) {             cgsize wordsize = [word sizewithattributes:@{nsfontattributename: labelfont}];             longestwordwidth = max(longestwordwidth, wordsize.width);         }          // loop until text @ current size fits maximum width/height.     } while (labelheightwithfont > buttonlabelmaxwidth || longestwordwidth > buttonlabelmaxwidth);      self.buttonlabel.text = title;     self.buttonlabel.font = labelfont; }  - (cgsize)boundingsizeforstring:(nsstring *)string font:(uifont *)font {      cgrect boundingrect = [string boundingrectwithsize:cgsizemake([self buttonlabelmaxwidth], maxfloat)                                 options:nsstringdrawinguseslinefragmentorigin | nsstringdrawingusesfontleading                              attributes:@{nsfontattributename: font}                                 context:nil];     return cgsizemake(ceilf(boundingrect.size.width), ceilf(boundingrect.size.height)); } 

Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -