How can I activate automatic hyphenation in iOS?
I have tried to set the hyphenation factor to 1 in the attributed text options of an UILabel, however I don\'t get
You need to add "soft hyphenation" to the string. These are "-" which is not visible when rendered, but instead merely queues for CoreText or UITextKit to know how to break up words.
The soft hyphen sign which you should place in the text is:
unichar const kTextDrawingSoftHyphenUniChar = 0x00AD;
NSString * const kTextDrawingSoftHyphenToken = @""; // NOTE: UTF-8 soft hyphen!
Example code
NSString *string = @"accessibility tests and frameworks checking";
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];
NSString *hyphenatedString = [string softHyphenatedStringWithLocale:locale error:nil];
NSLog(@"%@", hyphenatedString);
Outputs ac-ces-si-bil-i-ty tests and frame-works check-ing
typedef enum {
NSStringSoftHyphenationErrorNotAvailableForLocale
} NSStringSoftHyphenationError;
extern NSString * const NSStringSoftHyphenationErrorDomain;
@interface NSString (SoftHyphenation)
- (NSString *)softHyphenatedStringWithLocale:(NSLocale *)locale error:(out NSError **)error;
@end
NSString * const NSStringSoftHyphenationErrorDomain = @"NSStringSoftHyphenationErrorDomain";
@implementation NSString (SoftHyphenation)
- (NSError *)hyphen_createOnlyError
{
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: @"Hyphenation is not available for given locale",
NSLocalizedFailureReasonErrorKey: @"Hyphenation is not available for given locale",
NSLocalizedRecoverySuggestionErrorKey: @"You could try using a different locale even though it might not be 100% correct"
};
return [NSError errorWithDomain:NSStringSoftHyphenationErrorDomain code:NSStringSoftHyphenationErrorNotAvailableForLocale userInfo:userInfo];
}
- (NSString *)softHyphenatedStringWithLocale:(NSLocale *)locale error:(out NSError **)error
{
CFLocaleRef localeRef = (__bridge CFLocaleRef)(locale);
if(!CFStringIsHyphenationAvailableForLocale(localeRef))
{
if(error != NULL)
{
*error = [self hyphen_createOnlyError];
}
return [self copy];
}
else
{
NSMutableString *string = [self mutableCopy];
unsigned char hyphenationLocations[string.length];
memset(hyphenationLocations, 0, string.length);
CFRange range = CFRangeMake(0, string.length);
for(int i = 0; i < string.length; i++)
{
CFIndex location = CFStringGetHyphenationLocationBeforeIndex((CFStringRef)string,
i,
range,
0,
localeRef,
NULL);
if(location >= 0 && location < string.length)
{
hyphenationLocations[location] = 1;
}
}
for(int i = string.length - 1; i > 0; i--)
{
if(hyphenationLocations[i])
{
[string insertString:@"-" atIndex:i];
}
}
if(error != NULL) { *error = nil;}
return string;
}
}
@end
Swift version:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.hyphenationFactor = 1
paragraphStyle.alignment = .center
let string = NSAttributedString(string: "wyindywidualizowany indywidualista".uppercased(),
attributes: [NSParagraphStyleAttributeName : paragraphStyle])
myLabel.attributedText = string
UITextView
instead of an UILabel
. The hyphenationFactor
(either as a NSParagraphStyle
attribute or as a NSLayoutManager
property) should work then (thanks to the new TextKit).UIWebView
and the -webkit-hyphens
CSS properties.CFStringGetHyphenationLocationBeforeIndex()
function that you mentioned in a comment. This function only gives you a hint about where to put hyphens in a string for a specific language. Then you have to break your lines of text yourself using the Core Text functions (like CTLineCreateWithAttributedString()
and all). See Getting to Know TextKit (the paragraph called Hyphenation explains the logic of the Core Text process, with no code) and Hyphenation with Core Text on the iPad (gives some code sample, but the website seems to be down right now). It's probably going to be more work than you want!