سؤال

I'm floating some text around an image using CoreText and kCTJustifiedTextAlignment to show the text justiefied - but with larger images, smaller text-areas and less whitespaces CoreText does not only widen whitespaces but also the margin between the letters.

See here: badly justified

This sometimes looks really awful, so I searched for some alternatives or workarounds but only found the advice to do it myself by adding more whitespaces after each whitespace to match the width and using kCTLeftTextAlignment. It sounds like a lot of snares to deal with, so I thought, I'd ask here, maybe anyone has an idea how to deal with that issue.

هل كانت مفيدة؟

المحلول

The basic question here is "so what do you want?" The other obvious answer is "full justify unless... some rules I'm going to make up like if there's only one word."

If you want that kind of control, then you need to drop down to the CTLine level and create justified lines only when you want them. Assuming you already know a bit about CoreText, this code should hopefully make sense. It justifies the line only if it isn't the last line of the paragraph.

  CFIndex lineCharacterCount = CTTypesetterSuggestLineBreak(self.typesetter, startIndex, boundsWidth);
  CTLineRef line = CTTypesetterCreateLine(self.typesetter, CFRangeMake(startIndex, lineCharacterCount));

  // Fetch the typographic bounds
  CTLineGetTypographicBounds(line, &(*ascent), &(*descent), &(*leading));

  // Full-justify all but last line of paragraphs
  NSString *string = self.attributedString.string;
  NSUInteger endingLocation = startIndex + lineCharacterCount;
  if (endingLocation >= string.length || [string characterAtIndex:endingLocation] != '\n') {
    CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, 1.0, boundsWidth);
    CFRelease(line);
    line = justifiedLine;
  }

So we create a normal CTLine based on the CTTypesetter suggestion. Then we apply some rule (only one word? Not the end of the paragraph? Whatever.) If we pass, then we create a new, justified line. (I'm not certain why CTTypesetter can't create a justified line itself.)

For a full example of this, see PinchText. It's much more complicated than you need, but it shows how to do all the layout with lots of comments.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top