原生 iOS 应用程序中的断字

Posted

技术标签:

【中文标题】原生 iOS 应用程序中的断字【英文标题】:Hyphenation in native iOS app 【发布时间】:2013-10-31 14:39:58 【问题描述】:

如何在 ios 中激活自动断字?

我尝试在 UILabel 的属性文本选项中将连字符因子设置为 1,但是我没有得到任何连字符。

【问题讨论】:

在这里查看正确答案:***.com/questions/6968331/… html 中没有开箱即用的东西吗?我不想手动添加软连字符。 【参考方案1】:
    iOS 7 方式。使用UITextView 而不是UILabel。然后hyphenationFactor(作为NSParagraphStyle 属性或NSLayoutManager 属性)应该可以工作(感谢新的TextKit)。 网络方式。使用 UIWebView-webkit-hyphens CSS 属性。 核心文本或艰难的方式。使用您在评论中提到的 CFStringGetHyphenationLocationBeforeIndex() 函数。此函数仅提示您在特定语言的字符串中放置连字符的位置。然后你必须使用核心文本函数(如CTLineCreateWithAttributedString() 和所有)自己打破你的文本行。参见Getting to Know TextKit(名为Hyphenation 的段落解释了Core Text 过程的逻辑,没有代码)和Hyphenation with Core Text on the iPad(给出了一些代码示例,但该网站现在似乎已关闭)。工作量可能会超出您的预期!

【讨论】:

NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; paragraph.hyphenationFactor = 1; NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"asdf" attributes:[NSDictionary dictionaryWithObjectsAndKeys:paragraph, NSParagraphStyleAttributeName, nil]]; 也在为 UILabel 工作! @Guillaume 您是否设法让 (2) UIWebView 处理“-webkit-hyphens”?它确实在 iOS 模拟器中工作,但只是忽略了 iOS 设备上的“连字符”。 hyphenationFactor 设置为 1.0 并且设备的语言设置为非通用语言(即波兰语或克罗地亚语)时,连字词末尾缺少连字符破折号。 @Kubba 您是否找到了 hyphenationFactor 无法在波兰语和克罗地亚语等语言中工作的修复?我对爱沙尼亚语有同样的问题,但它适用于英语和德语 @Borbea 不。 Bug 仍然挂在 Apple 的 Bug Reporter 中【参考方案2】:

CoreText 或 TextKit

您需要在字符串中添加“软连字符”。这些是“-”,在渲染时不可见,而只是排队等待 CoreText 或 UITextKit 知道如何分解单词。

您应该在文本中放置的软连字符是:

unichar const kTextDrawingSoftHyphenUniChar = 0x00AD;
NSString * const kTextDrawingSoftHyphenToken = @"­"; // NOTE: UTF-8 soft hyphen!

示例代码

NSString *string = @"accessibility tests and frameworks checking";
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];
NSString *hyphenatedString = [string softHyphenatedStringWithLocale:locale error:nil];
NSLog(@"%@", hyphenatedString);

输出ac-ces-si-bil-i-ty tests and frame-works check-ing


NSString+SoftHyphenation.h

typedef enum 
    NSStringSoftHyphenationErrorNotAvailableForLocale
 NSStringSoftHyphenationError;

extern NSString * const NSStringSoftHyphenationErrorDomain;

@interface NSString (SoftHyphenation)

- (NSString *)softHyphenatedStringWithLocale:(NSLocale *)locale error:(out NSError **)error;

@end

NSString+SoftHyphenation.m

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

【讨论】:

非常好,谢谢!我正在使用 NSAttributedText 将连字符因子设置为 1。它也可以工作,但我更喜欢你的解决方案(因为它更通用)。 “这些是“-”,渲染时不可见“不是真的。如果我将连字符字符串设置为 UITextView 的文本,我仍然会看到这些破折号 @Spail 您是否 1000 % 确定您使用的是最上面代码示例中描述的软连字符? @hfossli 我的错。是的,如果您使用 @"\u00AD" 作为插入的字符串,它会起作用。谢谢! 使用 CTFrame 时不显示连字符 :( yadi.sk/i/sM3sEAkIqiVN2 在控制台中有 yadi.sk/i/-xjzpyubqiVRU【参考方案3】:

Swift 版本:

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.hyphenationFactor = 1
paragraphStyle.alignment = .center

let string = NSAttributedString(string: "wyindywidualizowany indywidualista".uppercased(),
                                attributes: [NSParagraphStyleAttributeName : paragraphStyle])

myLabel.attributedText = string

【讨论】:

以上是关于原生 iOS 应用程序中的断字的主要内容,如果未能解决你的问题,请参考以下文章

如何启用按音节自动断字?

Grails 应用程序上的断管异常

字母中的断词属性[重复]

支持原生 iOS 应用中的 chromecast

#yyds干活盘点# 5 Css3 文本效果

如何处理浏览器的断网情况?