Ios 使用cfStringGetHypenationLocationBeforeIndex添加连字符
我正在制作一本包含核心文本的杂志,并尝试自动在文本中添加连字符。我想我可以用这个函数来实现Ios 使用cfStringGetHypenationLocationBeforeIndex添加连字符,ios,objective-c,core-text,Ios,Objective C,Core Text,我正在制作一本包含核心文本的杂志,并尝试自动在文本中添加连字符。我想我可以用这个函数来实现 CFStringGetHyphenationLocationBeforeIndex 但它不起作用,我在网上找不到任何例子 我要做的是设置文本,如果我发现任何连字符位置,我会在那里放一个“-”,然后通过访问器替换文本,这样它就会调用setNeedsDisplay并从头开始绘制 - (void) setTexto:(NSAttributedString *)texto { _texto = tex
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);
}
}
}
-(void)setTexto:(nsattributestring*)texto{
_texto=texto;
if(self.ctFrame!=NULL){
CFRelease(self.ctFrame);
self.ctFrame=NULL;
}
[自我设置需要显示];
}
-(void)drawRect:(CGRect)rect{
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(上下文,CGAffineTransformity);
CGContextScaleCTM(上下文,1.0,-1.0);
CGMutablePathRef path=CGPathCreateMutable();
CGPathAddRect(路径,NULL,self.bounds);
CTFramesetterRef CTFramesetterRef=CTFramesetterCreateWithAttributedString((u桥CFAttributedStringRef)(texto));
self.ctFrame=CTFramesetterCreateFrame(ctFrameSetterRef,CFRangeMake(0,[[u texto length]),路径,NULL);
NSArray*行=(uu桥NSArray*)(CTFrameGetLines(self.ctFrame));
CFIndex lineCount=[行数];
NSLog(@“行数:%d”,行数.count);
对于(CFIndex idx=0;idx
问题是它第二次进入drawRect(使用新文本)行。将日志计数为0。而且我也不确定这是正确的方法
也许还有另一种方法可以修改CTLINE(在前一行的“-”之后添加剩余字符)。在创建属性化字符串之前,可以添加软连字符。然后你就可以画画了 我编写了一个类别,用于在任何字符串中添加“软连字符”。这些是“-”,在呈现时不可见,而只是排队等待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测试和框架工程检查
NSString+softhypernation.h NSString+SoftHyphenation.m
#导入“NSString+SoftHyphenation.h”
NSString*const NSStringSoftHyphenationErrorDomain=@“NSStringSoftHyphenationErrorDomain”;
NSString*const NSStringSoftHyphenationToken=@“…”;//注意:UTF-8软连字符!
@实现NSString(软断字)
-(BOOL)canSoftHyphenateStringWithLocale:(NSLocale*)locale
{
CFLocaleRef localeRef=(桥CFLocaleRef)(locale);
返回CFStringIsHyphenationAvailableForLocale(localeRef);
}
-(NSString*)软连字符StringWithLocale:(NSLocale*)区域设置错误:(out NSError**)错误
{
如果(![self-canSoftHyphenateStringWithLocale:locale])
{
if(错误!=NULL)
{
*错误=[self hyphen_createOnlyError];
}
返回[自复制];
}
其他的
{
NSMutableString*字符串=[self-mutableCopy];
无符号字符连字符位置[string.length];
memset(连字符位置,0,string.length);
CFRange range=CFRangeMake(0,string.length);
CFLocaleRef localeRef=(桥CFLocaleRef)(locale);
for(int i=0;i=0&&location0;i--)
{
if(连字符位置[i])
{
[string insertString:nsstringsofthyphentationtoken-atIndex:i];
}
}
如果(error!=NULL){*error=nil;}
//如果您想用可见的结果进行测试,请将其保留在此处
//返回[string stringByReplacingOccurrencesOfString:NSStringSofthyphenalationToken with string:@“-”];
返回字符串;
}
}
-(N错误*)连字符_createOnlyError
{
NSDictionary*用户信息=@{
NSLocalizedDescriptionKey:@“对于给定的区域设置,断字不可用”,
NSLocalizedFailureReasonErrorKey:@“断字不适用于给定区域设置”,
NSLocalizedRecoverysSuggestionErrorKey:@“您可以尝试使用不同的区域设置,即使它可能不是100%正确”
};
返回[NSErrorWithDomain:NSStringSoftHyphenationErrorDomain代码:NSStringSoftHyphenationErrorNotAvailableForLocale userInfo:userInfo];
}
@结束
希望这有帮助:)事实上确实有帮助。但是我的问题被问到了
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
#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