Расстановка переносов в родном приложении для iOS

Как я могу активировать автоматический перенос в iOS?

Я попытался установить коэффициент дефиса равным 1 в параметрах атрибутированного текста UILabel, однако я не получаю никаких дефисов.


person Chris    schedule 31.10.2013    source источник
comment
См. правильный ответ здесь: stackoverflow .com/questions/6968331/   -  person Nikos M.    schedule 31.10.2013
comment
Нет ничего нестандартного, как в HTML? Я не хочу ставить мягкие дефисы вручную.   -  person Chris    schedule 31.10.2013


Ответы (3)


  1. В стиле iOS 7. Используйте UITextView вместо UILabel. Тогда hyphenationFactor (либо как атрибут NSParagraphStyle, либо как свойство NSLayoutManager) должен работать (благодаря новому TextKit).
  2. Интернет-способ. Используйте свойства CSS UIWebView и -webkit-hyphens.
  3. Основной текст или трудный путь. Используйте функцию CFStringGetHyphenationLocationBeforeIndex(), которую вы упомянули в комментарии. Эта функция только дает вам подсказку о том, где ставить дефисы в строке для определенного языка. Затем вам нужно самостоятельно разбить строки текста, используя функции основного текста (например, CTLineCreateWithAttributedString() и все такое). См. Знакомство с TextKit (абзац под названием "Расстановка переносов" объясняет логика процесса основного текста без кода) и расстановка переносов с основным текстом на iPad (дает пример кода, но веб-сайт, похоже, сейчас не работает). Это, вероятно, будет больше работы, чем вы хотите!
person Guillaume    schedule 04.11.2013
comment
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; paragraph.hyphenationFactor = 1; NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"asdf" attributes:[NSDictionary dictionaryWithObjectsAndKeys:paragraph, NSParagraphStyleAttributeName, nil]]; тоже работает на UILabel! - person Chris; 05.11.2013
comment
@Guillaume Вам удалось заставить (2) UIWebView обрабатывать дефисы -webkit? Он работает в симуляторе iOS, но просто игнорирует дефисы на устройствах iOS. - person Alexander Smirnov; 27.03.2015
comment
когда hyphenationFactor установлено на 1.0, а язык устройства установлен на нераспространенный, т. е. польский или хорватский, в конце слова, написанного через дефис, отсутствует тире. - person Kubba; 07.03.2016
comment
@Kubba, возможно, вы нашли исправление для hyphenationFactor, не работающего на таких языках, как польский и хорватский? У меня такая же проблема с эстонским, но работает с английским и немецким - person Borbea; 30.09.2017
comment
@Борбеа, нет. Ошибка все еще висит в Apple Bug Reporter - person Kubba; 30.09.2017
comment
@Kubba спасибо за быстрый ответ. Очень плохо, что они до сих пор не исправили это - person Borbea; 30.09.2017
comment
@Borbea Я перепроверил это, обновил пример проекта до Swift 4, и на самом деле он исправлен, по крайней мере, на iOS 11. - person Kubba; 02.10.2017

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
person hfossli    schedule 08.11.2013
comment
Очень мило спасибо! Я использую NSAttributedText с коэффициентом переноса, равным 1. Это также работает, но мне больше нравится ваше решение (поскольку оно более общее). - person Chris; 08.11.2013
comment
Это - то, что не видно при рендеринге. Неправда. Если я установлю строку с дефисом в качестве текста UITextView, я все равно увижу эти тире - person Spail; 23.01.2015
comment
@Spail, вы на 1000% уверены, что используете мягкий знак дефиса, как описано в самом верхнем примере кода? - person hfossli; 23.01.2015
comment
@hfossli мой плохой. Да, это работает, если вы используете @­ как строку, которая вставляется. Спасибо! - person Spail; 23.01.2015
comment
При использовании CTFrame дефисы не отображаются :( yadi.sk/i/sM3sEAkIqiVN2 При этом в консоли yadi.sk/i/-xjzpyubqiVRU - person AlessandroDP; 04.04.2016

Быстрая версия:

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

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

myLabel.attributedText = string
person buxik    schedule 11.10.2017