ios开发之FTCoreText的使用

更新时间:2024-06-18 17:18:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

[无限互联]ios开发之FTCoreText的使用

本节要点:

1.FTCoreText的使用和功能 2.FTCoreText的结构简单说明 3.用法示例

FTCoreText的使用和功能

1.使用FTCoreText前须导入CoreText.framework框架才能使用

2.FTCoreTextView是一个开源的Objective-C界面组件,使用CoreText框架渲染可高度自定义的静态文本内容

FTCoreText的结构说明用法示例

注:FTCoreTextView主要负责静态文本界面内容,其中FTCoreTextStyle的属性来控制不同情况下绘制的形式

________________________________________________________________________________________________________________________ 1.FTCoreTextView 1.1 FTCoreTextView.h

重要的标签名和用于FTCoreTextView代理中

[objc] view plaincopy

1. 2. 3. 4. 5.

NSString *const FTCoreTextTagDefault ; NSString *const FTCoreTextTagImage ; NSString *const FTCoreTextTagBullet ; NSString *const FTCoreTextTagPage; NSString *const FTCoreTextTagLink ;

[objc] view plaincopy

1. 2. 3. 4. 5.

//用于代理

NSString *const FTCoreTextDataURL; NSString *const FTCoreTextDataName ; NSString *const FTCoreTextDataFrame ; NSString *const FTCoreTextDataAttributes;

1.1.1 FTCoreTextViewDelegate

[objc] view plaincopy

1. 2. 3. 4. 5. 6. 7.

@protocol FTCoreTextViewDelegate

@optional

- (void)coreTextView:(FTCoreTextView *)coreTextView receivedTouchOnData:(NSD

ictionary *)data;

- (void)coreTextViewfinishedRendering:(FTCoreTextView *)coreTextView; @end

1.2 FTCoreTextView.m 1.2.1 FTCoreTextCode

通过此类型来保存数据,便于增删检查等操作

[objc] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.

@interface FTCoreTextNode : NSObject

@property (nonatomic, assign) FTCoreTextNode *supernode; @property (nonatomic) NSArray *subnodes;

@property (nonatomic, copy) FTCoreTextStyle *style; @property (nonatomic) NSRange styleRange; @property (nonatomic) BOOL isClosed;

@property (nonatomic) NSInteger startLocation; @property (nonatomic) BOOL isLink; @property (nonatomic) BOOL isImage; @property (nonatomic) BOOL isBullet; @property (nonatomic) NSString *imageName;

- (NSString *)descriptionOfTree; - (NSString *)descriptionToRoot;

- (void)addSubnode:(FTCoreTextNode *)node;

- (void)adjustStylesAndSubstylesRangesByRange:(NSRange)insertedRange;

18. 19. 20. 21. 22. 23. 24. 25.

- (void)insertSubnode:(FTCoreTextNode *)subnode atIndex:(NSUInteger)index; - (void)insertSubnode:(FTCoreTextNode *)subnode beforeNode:(FTCoreTextNode *- (FTCoreTextNode *)previousNode; - (FTCoreTextNode *)nextNode; - (NSUInteger)nodeIndex;

- (FTCoreTextNode *)subnodeAtIndex:(NSUInteger)index; @end

)node;

1.2.2 部分方法介绍 *控制画图的方法

[objc] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.

- (void)drawRect:(CGRect)rect {

CGContextRef context = UIGraphicsGetCurrentContext();

[self.backgroundColor setFill]; CGContextFillRect(context, rect);

[self updateFramesetterIfNeeded];

CGMutablePathRef mainPath = CGPathCreateMutable();

if (!_path) {

CGPathAddRect(mainPath, NULL, CGRectMake(0, 0, self.bounds.size.widt } else {

CGPathAddPath(mainPath, NULL, _path); }

CTFrameRef drawFrame = CTFramesetterCreateFrame(_framesetter, CFRangeMak

if (drawFrame == NULL) {

if (_verbose) NSLog(@\, self.processedString); } else {

//draw images

if ([_images count] > 0) [self drawImages];

h, self.bounds.size.height));

e(0, 0), mainPath, NULL);

27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66.

if (_shadowColor) {

CGContextSetShadowWithColor(context, _shadowOffset, 0.f, _shadow }

CGContextSetTextMatrix(context, CGAffineTransformIdentity); CGContextTranslateCTM(context, 0, self.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); // draw text

CTFrameDraw(drawFrame, context); }

// cleanup

if (drawFrame) CFRelease(drawFrame); CGPathRelease(mainPath);

if ([_delegate respondsToSelector:@selector(coreTextViewfinishedRenderin [_delegate coreTextViewfinishedRendering:self]; } }

- (void)drawImages {

CGMutablePathRef mainPath = CGPathCreateMutable(); if (!_path) {

CGPathAddRect(mainPath, NULL, CGRectMake(0, 0, self.bounds.size.widt } else {

CGPathAddPath(mainPath, NULL, _path); }

CTFrameRef ctframe = CTFramesetterCreateFrame(_framesetter, CFRangeMake( CGPathRelease(mainPath);

NSArray *lines = (__bridge NSArray *)CTFrameGetLines(ctframe); NSInteger lineCount = [lines count]; CGPoint origins[lineCount];

CTFrameGetLineOrigins(ctframe, CFRangeMake(0, 0), origins);

FTCoreTextNode *imageNode = [_images objectAtIndex:0];

Color.CGColor);

g:)]) {

h, self.bounds.size.height));

0, 0), mainPath, NULL);

67. 68. 69.

for (int i = 0; i < lineCount; i++) { CGPoint baselineOrigin = origins[i];

//the view is inverted, the y origin of the baseline is upside down baselineOrigin.y = CGRectGetHeight(self.frame) - baselineOrigin.y;

CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:i]; CFRange cfrange = CTLineGetStringRange(line);

if (cfrange.location > imageNode.styleRange.location) { CGFloat ascent, descent;

CGFloat lineWidth = CTLineGetTypographicBounds(line, &ascent, &d

CGRect lineFrame = CGRectMake(baselineOrigin.x, baselineOrigin.y

CTTextAlignment alignment = (CTTextAlignment)imageNode.style.tex UIImage *img = nil;

if ([imageNode.imageName hasPrefix:@\]) {

NSData *myImgData = [NSData ftct_dataWithBase64EncodedString img = [UIImage imageWithData:myImgData]; } else {

img = [UIImage imageNamed:imageNode.imageName]; }

if (img) { int x = 0;

if (alignment == kCTRightTextAlignment) x = (self.frame.size if (alignment == kCTCenterTextAlignment) x = ((self.frame.si

CGRect frame = CGRectMake(x, (lineFrame.origin.y - img.size.

// adjusting frame

UIEdgeInsets insets = imageNode.style.paragraphInset;

70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101.

escent, NULL);

- ascent, lineWidth, ascent + descent);

tAlignment;

:[imageNode.imageName substringFromIndex:7]];

.width - img.size.width); ze.width - img.size.width) / 2);

height), img.size.width, img.size.height);

102.

if (alignment != kCTCenterTextAlignment) frame.origin.x = (a

lignment == kCTLeftTextAlignment)? insets.left : (self.frame.size.width - img.size.width - insets.right);

103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119.

frame.origin.y += insets.top;

frame.size.width = ((insets.left + insets.right + img.size.w

[img drawInRect:CGRectIntegral(frame)]; }

NSInteger imageNodeIndex = [_images indexOfObject:imageNode]; if (imageNodeIndex < [_images count] - 1) {

imageNode = [_images objectAtIndex:imageNodeIndex + 1]; } else { break; } } }

CFRelease(ctframe); }

idth ) > self.frame.size.width)? self.frame.size.width : img.size.width;

*通过touch方法来调用代理方法

[objc] view plaincopy

1. 2. 3. 4.

;

- (void)touchesBegan:(NSSet *)touches withEven

t:(UIEvent *)event

{

if (self.delegate && [self.delegate respondsToSelector:@selector(coreTex

tView:receivedTouchOnData:)]) {

CGPoint point = [(UITouch *)[touches anyObject] locationInView:self] NSMutableArray *activeRects;

NSDictionary *data = [self dataForPoint:point activeRects:&activeRec

ts];

if (data.count > 0) {

NSMutableArray *selectedViews = [NSMutableArray new]; for (NSString *rectString in activeRects) { CGRect rect = CGRectFromString(rectString); UIView *view = [[UIView alloc] initWithFrame:rect]; view.layer.cornerRadius = 3; view.clipsToBounds = YES;

5. 6. 7. 8. 9. 10. 11. 12. 13.

14.

;

view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.25] [self addSubview:view]; [selectedViews addObject:view]; }

self.touchedData = data;

self.selectionsViews = selectedViews; } }

[super touchesBegan:touches withEvent:event]; }

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

_touchedData = nil;

[_selectionsViews makeObjectsPerformSelector:@selector(removeFromSupervi _selectionsViews = nil;

[super touchesMoved:touches withEvent:event]; }

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

if (_touchedData) {

if (self.delegate && [self.delegate respondsToSelector:@selector(cor if ([self.delegate respondsToSelector:@selector(coreTextView:rec [self.delegate coreTextView:self receivedTouchOnData:_touche } }

_touchedData = nil;

[_selectionsViews makeObjectsPerformSelector:@selector(removeFromSup _selectionsViews = nil; }

[super touchesEnded:touches withEvent:event]; }

15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47.

ew)];

eTextView:receivedTouchOnData:)]) { eivedTouchOnData:)]) { dData];

erview)];

________________________________________________________________________________________________________________________ 2.FTCoreTextStyle 主要是配置属性

2.1 FTCoreTextStyle.h

[objc] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

ES.

@property (nonatomic) NSString *name;

e=\> //类型自定义名称

@property (nonatomic) NSString *appendedCharacter;

re\> //

@property (nonatomic) UIFont *font;

>//字体

@property (nonatomic) UIColor *color;

span>//颜色

@property (nonatomic, getter=isUnderLined) BOOL underlined;

e-space:pre\> //是否有下划线

@property (nonatomic) FTCoreTextAlignement textAlignment; //左右对齐方式

@property (nonatomic) UIEdgeInsets paragraphInset;

re\> //段落间隙

@property (nonatomic) CGFloat leading;

span>

@property (nonatomic) CGFloat maxLineHeight;

//行高

@property (nonatomic) CGFloat minLineHeight;

// For bullet styles only

@property (nonatomic) NSString *bulletCharacter;

// Called when the style is parsed for extra actions @property (nonatomic, copy) FTCoreTextCallbackBlock block;

// If NO, the paragraph styling of the enclosing style is used. Default is Y@property (nonatomic, assign) BOOL applyParagraphStyling;

\> //自定义的修饰符

21.

2.2 FTCoreTextStyle.m

初始化方法(实例方法和初始化方法创建)

[objc] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

- (id)init {

self = [super init]; if (self) {

_name = @\; _bulletCharacter = @\; _appendedCharacter = @\;

_font = [UIFont systemFontOfSize:12]; _color = [UIColor blackColor]; _underlined = NO;

_textAlignment = FTCoreTextAlignementLeft; _maxLineHeight = 0; _minLineHeight = 0;

_paragraphInset = UIEdgeInsetsZero; _applyParagraphStyling = YES; _leading = 0; _block = nil; }

return self; }

[objc] view plaincopy

1. 2. 3. 4. 5. 6.

+ (id)styleWithName:(NSString *)name {

FTCoreTextStyle *style = [[FTCoreTextStyle alloc] init]; [style setName:name]; return style; }

———————————————————————————————————————————————————————————————————

用法示例

[objc] view plaincopy

1.

FTCoreTextView *coreText

View = [[FTCoreTextView alloc] initWithFrame:CGRectInset(bounds, 20.0f, 0)];

[objc] view plaincopy

1.

coreTextView.dele

gate = self;

[objc] view plaincopy

1. 2. 3.

FTCoreTextStyle *imageStyle = [FTCoreTextStyle styleWithName:FTCoreTextTagIm

age];

imageStyle.textAlignment = FTCoreTextAlignementCenter; [self.coreTextView addStyle:imageStyle];

[objc] view plaincopy

1. 2. 3. 4. 5. 6.

- (void)viewDidLayoutSubviews {

[super viewDidLayoutSubviews];

// We need to recalculate fit height on every layout because // when the device orientation changes, the FTCoreText's width changes

// Make the FTCoreTextView to automatically adjust it's height // so it fits all its rendered text using the actual width [self.coreTextView fitToSuggestedHeight]; }

7. 8. 9. 10. 11.

本文来源:https://www.bwwdw.com/article/w9q3.html

Top