iOS-CoreText的那些事,ios-coretext那些事

來源:互聯網
上載者:User

iOS-CoreText的那些事,ios-coretext那些事
1.判斷點擊的位置是否在某個NSRange範圍內

#pragma mark 判斷點擊的位置是否在 range內/** 將點擊的位置轉換成字串的位移量,如果沒有找到,則返回-1 view:view point:點擊位置 frameRef:當前view的frameRef */+ (CFIndex)wkj_touchContentOffsetInView:(UIView *)view                            point:(CGPoint)point                           frameRef:(CTFrameRef)frameRef{    CTFrameRef textFrame = frameRef;    CFArrayRef lines = CTFrameGetLines(textFrame);    if (!lines) {        return -1;    }    CFIndex count = CFArrayGetCount(lines);        // 獲得每一行的origin座標    CGPoint origins[count];    CTFrameGetLineOrigins(textFrame, CFRangeMake(0,0), origins);        // 翻轉座標系    CGAffineTransform transform =  CGAffineTransformMakeTranslation(0, view.bounds.size.height);    transform = CGAffineTransformScale(transform, 1.f, -1.f);        CFIndex idx = -1;    for (int i = 0; i < count; i++) {        CGPoint linePoint = origins[i];        CTLineRef line = CFArrayGetValueAtIndex(lines, i);        // 獲得每一行的CGRect資訊        CGRect flippedRect = [self wkj_getLineBounds:line point:linePoint];        CGRect rect = CGRectApplyAffineTransform(flippedRect, transform);                if (CGRectContainsPoint(rect, point)) {            // 將點擊的座標轉換成相對於當前行的座標cocoapods            CGPoint relativePoint = CGPointMake(point.x-CGRectGetMinX(rect),                                                point.y-CGRectGetMinY(rect));            // 獲得當前點擊座標組應的字串位移            idx = CTLineGetStringIndexForPosition(line, relativePoint);        }    }    return idx;}+ (CGRect)wkj_getLineBounds:(CTLineRef)line point:(CGPoint)point {    CGFloat ascent = 0.0f;    CGFloat descent = 0.0f;    CGFloat leading = 0.0f;    CGFloat width = (CGFloat)CTLineGetTypographicBounds(line, &ascent, &descent, &leading);    CGFloat height = ascent + descent;    return CGRectMake(point.x, point.y - descent, width, height);}/** 此處判斷 根據上面返回的字串的位移量,對比range是否在點擊的位置 */+ (BOOL)wkj_judgeAtIndex:(CFIndex)index range:(NSRange)range {    if (NSLocationInRange(index, range)) {        ///點擊處在range內        return YES;    }    return NO;}

 

 

2.通過CFRange與CTFrameRef擷取要操作(塗色,劃線)的CGRect數組
#pragma mark 通過range擷取rect集合【用於劃線、塗色】+ (NSArray*)wkj_frameGetFrameOfStringInRange:(CTFrameRef)frameRef range:(CFRange)range{    CFRange frameRefRange = CTFrameGetStringRange(frameRef);    range = [self wkj_cfRangeInsection:frameRefRange range:range];    if ([self wkj_cfRangeEqualToRange:range range:CFRangeZero]) {        return nil;    }        NSArray *lines = (NSArray*)CTFrameGetLines(frameRef);    NSInteger lineCount = [lines count];    //擷取整個CTFrame的大小    CGPathRef path = CTFrameGetPath(frameRef);    CGRect frameRefRect = CGPathGetBoundingBox(path);    //擷取所有行的起點    CGPoint *origins = (CGPoint*)malloc(lineCount * sizeof(CGPoint));    CTFrameGetLineOrigins(frameRef, CFRangeMake(0, 0), origins);    NSMutableArray *rects = [NSMutableArray array];    for (CFIndex index = 0; index<lines.count; index++) {        CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:index];        CFRange rangeOfLine = CTLineGetStringRange(line);        CFRange rangeOfInsection = [self wkj_cfRangeInsection:rangeOfLine range:range];        if (![self wkj_cfRangeEqualToRange:rangeOfInsection range:CFRangeZero]) {            CGRect frame = [self wkj_lineGetFrame:line point:origins[index] range:rangeOfInsection];            frame = CGRectOffset(frame, frameRefRect.origin.x, frameRefRect.origin.y);                        [rects addObject:[NSValue valueWithCGRect:frame]];        }    }    free(origins);    return [rects copy];}+ (CGRect)wkj_lineGetFrame:(CTLineRef)line                     point:(CGPoint)origin                     range:(CFRange)range{    CFRange lineRange = CTLineGetStringRange(line);    range = [self wkj_cfRangeInsection:lineRange range:range];    CGFloat trailingWhitespaceWidth = CTLineGetTrailingWhitespaceWidth(line);    if ([self wkj_cfRangeGetEndLocation:range]==[self wkj_cfRangeGetEndLocation:lineRange]&&trailingWhitespaceWidth>0) {        --range.length;    }    CGFloat xStart = CTLineGetOffsetForStringIndex(line, range.location, NULL);    CGFloat xEnd = CTLineGetOffsetForStringIndex(line, [self wkj_cfRangeGetEndLocation:range]+1, NULL);        CGFloat ascent, descent, leading;        CTLineGetTypographicBounds(line, &ascent, &descent, &leading);    CGRect selectionRect = CGRectMake(origin.x + xStart,                                      origin.y - descent,                                      xEnd - xStart,                                      ascent + descent + leading);        return selectionRect;}+ (CFRange)wkj_cfRangeInsection:(CFRange)range1 range:(CFRange)range2{    if ([self wkj_cfRangeGreaterThanRange:range1 range:range2]||[self wkj_cfRangeGreaterThanRange:range2 range:range1]) {        return CFRangeZero;    }    CFIndex beginLocation = MAX(range1.location, range2.location);    CFIndex endLocation = MIN([self wkj_cfRangeGetEndLocation:range1], [self wkj_cfRangeGetEndLocation:range2]);        return [self wkj_cfRangeMakeWithInterval:beginLocation endIndex:endLocation];}+ (BOOL)wkj_cfRangeGreaterThanRange:(CFRange)range1 range:(CFRange)range2{    return range1.location>[self wkj_cfRangeGetEndLocation:range2];}+ (CFIndex)wkj_cfRangeGetEndLocation:(CFRange)range{    return range.location+range.length-1;}+ (CFRange)wkj_cfRangeMakeWithInterval:(CFIndex)startIndex endIndex:(CFIndex)endIndex{    return CFRangeMake(startIndex, endIndex - startIndex + 1);}+ (BOOL)wkj_cfRangeEqualToRange:(CFRange)range1 range:(CFRange)range2{    return range1.location == range2.location&&range1.length==range2.length;}
 3.塗色劃線
- (void)wkj_drawLineForSelectArea{    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextSetFillColorWithColor(context, [[UIColor redColor] colorWithAlphaComponent:0.3].CGColor);    for (NSValue *rectValue in _arraySelectRect) {        CGRect rect = [rectValue CGRectValue];        rect.origin.y -= 2.5;        ///劃線時可設定高度為1  塗色是可根據字型大小設定        rect.size.height = 1;        rect.size.width -= 1.5;        CGContextFillRect(context, rect);    }}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.