日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > CoreText(五):省略號

CoreText(五):省略號

來源:程序員人生   發布時間:2016-12-08 17:10:01 閱讀次數:2628次

直接附代碼:

#import "MyView.h" #import <CoreText/CoreText.h> // 行距 const CGFloat kGlobalLineLeading = 5.0; // 在15字體下,比值小于這個計算出來的高度會致使emoji顯示不全 const CGFloat kPerLineRatio = 1.4; @interface MyView() @property (nonatomic ,assign) CGFloat textHeight; @end @implementation MyView - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.text = @"我自橫刀向天笑,去留肝膽兩昆侖。--譚嗣同同學你好啊。This is my first CoreText demo,how are you ?I love three things,the sun,the moon,and you.the sun for the day,the moon for the night,and you forever.??????????????去年本日此門中,人面桃花相映紅。人面不知何處去,桃花照舊笑春風。??????????????少年不知愁滋味,愛上層樓,愛上層樓,為賦新詞強說愁。56321363464.而今識盡愁滋味,欲說還休,欲說還休,卻道天涼好個秋。123456,7890,56321267895434。缺月掛疏桐,漏斷人初靜。誰見幽人獨來往,縹緲孤鴻影。驚起卻回頭,有恨無人省。撿盡寒枝不肯棲,孤單沙洲冷。"; self.font = [UIFont systemFontOfSize:15]; } return self; } /** * 高度 = 每行的固定高度 * 行數 */ + (CGFloat)textHeightWithText:(NSString *)aText width:(CGFloat)aWidth font:(UIFont *)aFont{ NSMutableAttributedString *content = [[NSMutableAttributedString alloc] initWithString:aText]; // 給字符串設置字體行距等樣式 [self addGlobalAttributeWithContent:content font:aFont]; CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)content); // 粗略的高度,該高度不準,僅供參考 CGSize suggestSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetterRef, CFRangeMake(0, content.length), NULL, CGSizeMake(aWidth, MAXFLOAT), NULL); NSLog(@"suggestHeight = %f",suggestSize.height); CGMutablePathRef pathRef = CGPathCreateMutable(); CGPathAddRect(pathRef, NULL, CGRectMake(0, 0, aWidth, suggestSize.height)); CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, content.length), pathRef, NULL); CFArrayRef lines = CTFrameGetLines(frameRef); CFIndex lineCount = CFArrayGetCount(lines); NSLog(@"行數 = %ld",lineCount); // 總高度 = 行數*每行的高度,其中每行的高度為指定的值,不同字體大小不1樣 CGFloat accurateHeight = lineCount * (aFont.pointSize * kPerLineRatio); CGFloat height = accurateHeight; CFRelease(pathRef); CFRelease(frameRef); return height; } #pragma mark - 工具方法 #pragma mark 給字符串添加全局屬性,比如行距,字體大小,默許色彩 + (void)addGlobalAttributeWithContent:(NSMutableAttributedString *)aContent font:(UIFont *)aFont { CGFloat lineLeading = kGlobalLineLeading; // 行間距 const CFIndex kNumberOfSettings = 2; //設置段落格式 CTParagraphStyleSetting lineBreakStyle; CTLineBreakMode lineBreakMode = kCTLineBreakByWordWrapping; lineBreakStyle.spec = kCTParagraphStyleSpecifierLineBreakMode; lineBreakStyle.valueSize = sizeof(CTLineBreakMode); lineBreakStyle.value = &lineBreakMode; //設置行距 CTParagraphStyleSetting lineSpaceStyle; CTParagraphStyleSpecifier spec; spec = kCTParagraphStyleSpecifierLineSpacingAdjustment; lineSpaceStyle.spec = spec; lineSpaceStyle.valueSize = sizeof(CGFloat); lineSpaceStyle.value = &lineLeading; // 結構體數組 CTParagraphStyleSetting theSettings[kNumberOfSettings] = { lineBreakStyle, lineSpaceStyle, }; CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, kNumberOfSettings); // 將設置的行距利用于整段文字 [aContent addAttribute:NSParagraphStyleAttributeName value:(__bridge id)(theParagraphRef) range:NSMakeRange(0, aContent.length)]; CFStringRef fontName = (__bridge CFStringRef)aFont.fontName; CTFontRef fontRef = CTFontCreateWithName(fontName, aFont.pointSize, NULL); // 將字體大小利用于整段文字 [aContent addAttribute:NSFontAttributeName value:(__bridge id)fontRef range:NSMakeRange(0, aContent.length)]; // 給整段文字添加默許色彩 [aContent addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, aContent.length)]; // 內存管理 CFRelease(theParagraphRef); CFRelease(fontRef); } #pragma mark - 1行1行繪制,行高肯定,行與行之間對齊 #pragma mark - 1行1行繪制,行高肯定,高度不夠時加上省略號 - (void)drawRectWithLineByLineAlignmentAndEllipses{ // 1.創建需要繪制的文字 NSMutableAttributedString *attributed = [[NSMutableAttributedString alloc] initWithString:self.text]; // 2.設置行距等樣式 [[self class] addGlobalAttributeWithContent:attributed font:self.font]; self.textHeight = [[self class] textHeightWithText:self.text width:CGRectGetWidth(self.bounds) font:self.font]; // 3.創建繪制區域,path的高度對繪制有直接影響,如果高度不夠,則計算出來的CTLine的數量會少1行或少多行 CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, CGRectMake(0, 0, CGRectGetWidth(self.bounds), self.textHeight*2)); // 4.根據NSAttributedString生成CTFramesetterRef CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributed); CTFrameRef ctFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path, NULL); // 重置高度 CGFloat realHeight = self.textHeight; // 繪制全部文本需要的高度大于實際高度則調劑,并加上省略號 if (realHeight > CGRectGetHeight(self.frame)){ realHeight = CGRectGetHeight(self.frame); } NSLog(@"realHeight = %f",realHeight); // 獲得上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); // 轉換坐標系 CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity); CGContextTranslateCTM(contextRef, 0, realHeight); // 這里隨著調劑 CGContextScaleCTM(contextRef, 1.0, -1.0); // 這里可調劑可不調劑 CGPathAddRect(path, NULL, CGRectMake(0, 0, CGRectGetWidth(self.bounds), realHeight)); // 1行1行繪制 CFArrayRef lines = CTFrameGetLines(ctFrame); CFIndex lineCount = CFArrayGetCount(lines); CGPoint lineOrigins[lineCount]; // 把ctFrame里每行的初始坐標寫到數組里,注意CoreText的坐標是左下角為原點 CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins); CGFloat frameY = 0; for (CFIndex i = 0; i < lineCount; i++){ // 遍歷每行CTLine CTLineRef line = CFArrayGetValueAtIndex(lines, i); CGFloat lineAscent; CGFloat lineDescent; CGFloat lineLeading; // 行距 // 該函數除會設置好ascent,descent,leading以外,還會返回這行的寬度 CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading); //CoreText的origin的Y值是在baseLine處,而不是下方的descent。 CGPoint lineOrigin = lineOrigins[i]; //行高 CGFloat lineHeight = self.font.pointSize * kPerLineRatio; //self.font.descender為負值 frameY = realHeight - (i + 1)*lineHeight - self.font.descender; NSLog(@"frameY = %f",frameY); lineOrigin.y = frameY; //調劑坐標 CGContextSetTextPosition(contextRef, lineOrigin.x, lineOrigin.y); if (frameY + self.font.descender > lineHeight){ CTLineDraw(line, contextRef); }else{ NSLog(@"最后1行"); // 最后1行,加上省略號 static NSString* const kEllipsesCharacter = @"\u2026"; CFRange lastLineRange = CTLineGetStringRange(line); // 1個emoji表情占用兩個長度單位 NSLog(@"range.location = %ld,range.length = %ld,總長度 = %ld",lastLineRange.location,lastLineRange.length,attributed.length); if (lastLineRange.location + lastLineRange.length < (CFIndex)attributed.length){ // 這1行放不下所有的字符(下1行還有字符),則把此行后面的回車、空格符去掉后,再把最后1個字符替換成省略號 CTLineTruncationType truncationType = kCTLineTruncationEnd; NSUInteger truncationAttributePosition = lastLineRange.location + lastLineRange.length - 1; // 拿到最后1個字符的屬性字典 NSDictionary *tokenAttributes = [attributed attributesAtIndex:truncationAttributePosition effectiveRange:NULL]; // 給省略號字符設置字體大小、色彩等屬性 NSAttributedString *tokenString = [[NSAttributedString alloc] initWithString:kEllipsesCharacter attributes:tokenAttributes]; // 用省略號單獨創建1個CTLine,下面在截斷重新生成CTLine的時候會用到 CTLineRef truncationToken = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)tokenString); // 把這1行的屬性字符串復制1份,如果要把省略號放到中間或其他位置,只需指定復制的長度便可 NSUInteger copyLength = lastLineRange.length; NSMutableAttributedString *truncationString = [[attributed attributedSubstringFromRange:NSMakeRange(lastLineRange.location, copyLength)] mutableCopy]; if (lastLineRange.length > 0) { // Remove any whitespace at the end of the line. unichar lastCharacter = [[truncationString string] characterAtIndex:copyLength - 1]; // 如果復制字符串的最后1個字符是換行、空格符,則刪掉 if ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:lastCharacter]) { [truncationString deleteCharactersInRange:NSMakeRange(copyLength - 1, 1)]; } } // 拼接省略號到復制字符串的最后 [truncationString appendAttributedString:tokenString]; // 把新的字符串創建成CTLine CTLineRef truncationLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)truncationString); // 創建1個截斷的CTLine,該方法不能少,具體作用還有待研究 CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, self.frame.size.width, truncationType, truncationToken); if (!truncatedLine) { // If the line is not as wide as the truncationToken, truncatedLine is NULL truncatedLine = CFRetain(truncationToken); } CFRelease(truncationLine); CFRelease(truncationToken); CTLineDraw(truncatedLine, contextRef); CFRelease(truncatedLine); } else{ // 這1行恰好是最后1行,且最后1行的字符可以完全繪制出來 CTLineDraw(line, contextRef); } // 跳出循環,避免繪制剩下的過剩的CTLine break; } } CFRelease(path); CFRelease(framesetter); CFRelease(ctFrame); } - (void)drawRect:(CGRect)rect { [self drawRectWithLineByLineAlignmentAndEllipses]; } @end

調用:

- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; // Do any additional setup after loading the view, typically from a nib. MyView *view = [[MyView alloc]initWithFrame:CGRectMake(0, 20, self.view.width, 100)]; view.backgroundColor = [UIColor redColor]; view.text = @"我自橫刀向天笑,去留肝膽兩昆侖。--譚嗣同同學你好啊。This is my first CoreText demo,how are you ?I love three things,the sun,the moon,and you.the sun for the day,the moon for the night,and you forever.??????????????去年本日此門中,人面桃花相映紅。人面不知何處去,桃花照舊笑春風。??????????????少年不知愁滋味,愛上層樓,愛上層樓,為賦新詞強說愁。56321363464.而今識盡愁滋味,欲說還休,欲說還休,卻道天涼好個秋。123456,7890,56321267895434。缺月掛疏桐,漏斷人初靜。誰見幽人獨來往,縹緲孤鴻影。驚起卻回頭,有恨無人省。撿盡寒枝不肯棲,孤單沙洲冷。"; view.font = [UIFont systemFontOfSize:15]; [self.view addSubview:view]; }

結果:
這里寫圖片描述

參考:
CoreText使用教程(4)

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 蜜桃视频一区二区三区在线观看 | 天堂中文资源在线 | 国产日韩欧美在线 | 69视频免费 | 国产精品18hdxxxⅹ在线 | 国产精品视频免费观看 | 91精品国产二区在线看大桥未久 | 日韩一区av | 国产精品日韩在线观看 | 日韩午夜激情 | 国产精品成人在线观看 | 天堂国产 | 久久久噜噜噜久久中文字幕色伊伊 | 在线麻豆 | 欧美亚洲天堂 | 久久亚洲综合国产精品99麻豆精品福利 | 国产乱码精品一区二区三区不卡 | 精品久| 亚洲国产精品一区二区第一页 | 国产一区| jizz18免费| 日本免费在线观看 | 国产不卡视频一区二区三区 | 成年人免费网站 | 99re在线免费视频 | 久久女人| 国产精品一区二区在线看 | 亚洲欧洲成人av每日更新 | 久久日韩精品 | 国产精品第157页 | 亚洲欧美综合色 | av最新| 国产一区二区在线视频观看 | 国产成人久久久 | 国产精品一区二区在线 | 国产激情视频在线 | 亚洲最大黄网 | 91精品久久久久久久久久不卡 | 午夜精品久久久久久久96蜜桃 | 天堂a√在线 | 欧美成人第一页 |