Attributed text, replace a specific font by another using swift -


i'm using attributed text in uitextview. text contain many fonts.

i'm looking way replace particular font one.

any swift approach this? :)

my code in objective-c, since use both cocoatouch, should same logic.

the method use enumerateattribute:inrange:options:usingblock: nsfontattributename.

there point isn't discussed: how recognize font 1 searched. looking familyname, fontname (property of uifont? in same family, font may lot different , may want search 1 matching same name. i've discussed once font names here. may found interesting in case. note there methods (that didn't know @ time) can bold name of font if available (or italic, etc.)

the main code in objective-c one:

[attrstring enumerateattribute:nsfontattributename                            inrange:nsmakerange(0, [attrstring length])                            options:0                         usingblock:^(id value, nsrange range, bool *stop) {                             uifont *currentfont = (uifont *)value; //font applied in range                             if ([self isfont:currentfont sameas:searchedfont]) //this can tricky                             {                             [attrstring addattribute:nsfontattributename                                                value:replacementfont                                                range:range];                             }     }]; 

possible change/adaptation according needs: change font, not size:

[attrstring addattribute:nsfontattributename value:[uifont fontwithname:replacefontname size:currentfont.pointsize]; range:range]; 

sample test code:

uifont *replacementfont = [uifont boldsystemfontofsize:12]; uifont *searchedfont    = [uifont fontwithname:@"helvetica neue" size:15]; uifont *normalfont      = [uifont italicsystemfontofsize:14];  nsmutableattributedstring *attrstring = [[nsmutableattributedstring alloc] initwithstring:@"lorem ipsum dolor sit amet,"];  nsattributedstring *attrstr1 = [[nsattributedstring alloc] initwithstring:@"consectetuer adipiscing elit." attributes:@{nsfontattributename:searchedfont, nsforegroundcolorattributename:[uicolor redcolor]}];  nsattributedstring *attrstr2 = [[nsattributedstring alloc] initwithstring:@" aenean commodo ligula eget dolor." attributes:@{nsfontattributename:normalfont}];  nsattributedstring *attrstr3 = [[nsattributedstring alloc] initwithstring:@" aenean massa." attributes:@{nsfontattributename:searchedfont}];  nsattributedstring *attrstr4 = [[nsattributedstring alloc] initwithstring:@"cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. nulla consequat massa quis enim."];  [attrstring appendattributedstring:attrstr1]; [attrstring appendattributedstring:attrstr2]; [attrstring appendattributedstring:attrstr3]; [attrstring appendattributedstring:attrstr4];  nslog(@"attrstring: %@", attrstring);  [attrstring enumerateattribute:nsfontattributename                        inrange:nsmakerange(0, [attrstring length])                        options:0                     usingblock:^(id value, nsrange range, bool *stop) {                         uifont *currentfont = (uifont *)value;                         if ([self isfont:currentfont sameas:searchedfont])                         {             [attrstring addattribute:nsfontattributename                                value:replacementfont                                range:rangeeffect];                         } }];  nslog(@"attrstring changed: %@", attrstring); 

with solution of @tigercoding, here possible code:

nsinteger location = 0; while (location < [attrstring length]) {     nsrange rangeeffect;     nsdictionary *attributes = [attrstring attributesatindex:location effectiverange:&rangeeffect];     if (attributes[nsfontattributename])     {         uifont *font = attributes[nsfontattributename];         if ([self isfont:font sameas:searchedfont])         {             [attrstring addattribute:nsfontattributename value:replacementfont range:rangeeffect];         }     }     location+=rangeeffect.length; } 

as side note: few optimization test (but need research). think few example if apply same attributes 2 consecutive range, nsattributedstring "appends them" one, in case may afraid apply same effect consecutively. question if have @{nsfontattributename:font1, nsforegroundcolorattributename:color1} range 0,3 , @{nsfontattributename:font1, nsforegroundcolorattributename:color2} range 3,5 enumerateattribute:inrange:options:usingblock: return range 0,5? faster enumerating each indexes?


Comments

Popular posts from this blog

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -

YouTubePlayerFragment cannot be cast to android.support.v4.app.Fragment -