Добавление дефис с CFStringGetHyphenationLocationBeforeIndex

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

CFStringGetHyphenationLocationBeforeIndex 

Но он не работает, и я не могу найти примеры в Интернете.

То, что я пытаюсь сделать, это настроить текст, и если я найду какую-либо дефисную позицию, я поставлю «-» там и заменим текст через аксессуар, чтобы он вызывал setNeedsDisplay и снова рисовал с нуля.

 - (void) setTexto:(NSAttributedString *)texto { _texto = texto; if (self.ctFrame != NULL) { CFRelease(self.ctFrame); self.ctFrame = NULL; } [self setNeedsDisplay]; } -(void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetTextMatrix(context, CGAffineTransformIdentity); CGContextScaleCTM(context, 1.0, -1.0); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, self.bounds); CTFramesetterRef ctFrameSetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(_texto)); self.ctFrame = CTFramesetterCreateFrame(ctFrameSetterRef, CFRangeMake(0, [_texto length]), path, NULL); NSArray *lines = (__bridge NSArray *)(CTFrameGetLines(self.ctFrame)); CFIndex lineCount = [lines count]; NSLog(@"lines: %d", lines.count); for(CFIndex idx = 0; idx < lineCount; idx++) { CTLineRef line = CFArrayGetValueAtIndex((CFArrayRef)lines, idx); CFRange lineStringRange = CTLineGetStringRange(line); NSRange lineRange = NSMakeRange(lineStringRange.location, lineStringRange.length); NSString* lineString = [self.texto.string substringWithRange:lineRange]; CFStringRef localeIdent = CFSTR("es_ES"); CFLocaleRef localeRef = CFLocaleCreate(kCFAllocatorDefault, localeIdent); NSUInteger breakAt = CFStringGetHyphenationLocationBeforeIndex((__bridge CFStringRef)lineString, lineRange.length, CFRangeMake(0, lineRange.length), 0, localeRef, NULL); if(breakAt!=-1) { NSRange replaceRange = NSMakeRange(lineRange.location+breakAt, 0); NSMutableAttributedString* attributedString = self.texto.mutableCopy; [attributedString replaceCharactersInRange:replaceRange withAttributedString:[[NSAttributedString alloc] initWithString:@"-"]]; self.texto = attributedString.copy; break; } else { CGFloat ascent; CGFloat descent; CTLineGetTypographicBounds(line, &ascent, &descent, nil); CGContextSetTextPosition(context, 0.0, idx*-(ascent - 1 + descent)-ascent); CTLineDraw(line, context); } } } 

Проблема заключается во второй раз, когда он переходит в drawRect (с новым текстом). Лист log.count равен 0. И также я не уверен, что это правильный способ сделать это.

Возможно, есть еще один способ изменения CTLines (добавление оставшихся символов после «-» из предыдущей строки).

Перед созданием атрибутной строки вы можете добавить мягкую перенос. Затем вы можете сделать рисунок.

Я написал категорию для добавления «мягкой переносов» к любой строке. Это «-», которые не отображаются при визуализации, а вместо этого просто очереди для CoreText или UITextKit, чтобы знать, как разбить слова.

 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; extern NSString * const NSStringSoftHyphenationToken; @interface NSString (SoftHyphenation) - (BOOL)canSoftHyphenateStringWithLocale:(NSLocale *)locale; - (NSString *)softHyphenatedStringWithLocale:(NSLocale *)locale error:(out NSError **)error; @end 

NSString + SoftHyphenation.m

 #import "NSString+SoftHyphenation.h" NSString * const NSStringSoftHyphenationErrorDomain = @"NSStringSoftHyphenationErrorDomain"; NSString * const NSStringSoftHyphenationToken = @""; // NOTE: UTF-8 soft hyphen! @implementation NSString (SoftHyphenation) - (BOOL)canSoftHyphenateStringWithLocale:(NSLocale *)locale { CFLocaleRef localeRef = (__bridge CFLocaleRef)(locale); return CFStringIsHyphenationAvailableForLocale(localeRef); } - (NSString *)softHyphenatedStringWithLocale:(NSLocale *)locale error:(out NSError **)error { if(![self canSoftHyphenateStringWithLocale:locale]) { 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); CFLocaleRef localeRef = (__bridge CFLocaleRef)(locale); 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:NSStringSoftHyphenationToken atIndex:i]; } } if(error != NULL) { *error = nil; } // Left here in case you want to test with visible results // return [string stringByReplacingOccurrencesOfString:NSStringSoftHyphenationToken withString:@"-"]; return string; } } - (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]; } @end 

Надеюсь это поможет 🙂

Interesting Posts
Давайте будем гением компьютера.