ctrundelegate学习

我们从 Run Delegate Types Run Delegate Callbacks Run Delegate Versions Run Delegate Creation Run Delegate Access 五个方面来学习

1.Run Delegate Types

1
CFTypeID CTRunDelegateGetTypeID( void ) CT_AVAILABLE(10_5, 3_2);

2.Run Delegate Callbacks

1
2
typedef void (*CTRunDelegateDeallocateCallback) (
void * refCon );
1
2
typedef CGFloat (*CTRunDelegateGetAscentCallback) (
void * refCon );
1
2
typedef CGFloat (*CTRunDelegateGetDescentCallback) (
void * refCon );
1
2
typedef CGFloat (*CTRunDelegateGetWidthCallback) (
void * refCon );
1
2
3
4
5
6
7
8
typedef struct
{
CFIndex version;
CTRunDelegateDeallocateCallback dealloc;
CTRunDelegateGetAscentCallback getAscent;
CTRunDelegateGetDescentCallback getDescent;
CTRunDelegateGetWidthCallback getWidth;
} CTRunDelegateCallbacks;

代码:

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
27
28
29
30
31
void CTRunDelegateDeallocateCallbackFunction (void * refCon ){
}
CGFloat CTRunDelegateGetAscentCallbackFunction (void * refCon ){
return 30;
}
CGFloat CTRunDelegateGetDescentCallbackFunction (void * refCon ){
return 30;
}
CGFloat CTRunDelegateGetWidthCallbackFunction(void * refCon ){
return 30;
}
CTRunDelegateDeallocateCallback deallocateCallback= CTRunDelegateDeallocateCallbackFunction;
NSLog(@"CTRunDelegateGetAscentCallback 获取ascent");
CTRunDelegateGetAscentCallback ascentCallback= CTRunDelegateGetAscentCallbackFunction;
CTRunDelegateGetDescentCallback descentCallback = CTRunDelegateGetDescentCallbackFunction;
CTRunDelegateGetWidthCallback widthCallBack = CTRunDelegateGetWidthCallbackFunction;
CTRunDelegateCallbacks callBack ;
callBack.version =kCTRunDelegateCurrentVersion;
callBack.dealloc = deallocateCallback;
callBack.getAscent = ascentCallback;
callBack.getDescent = descentCallback;
callBack.getWidth = widthCallBack;

3.Run Delegate Versions

1
2
3
4
enum {
kCTRunDelegateVersion1 = 1,
kCTRunDelegateCurrentVersion = kCTRunDelegateVersion1
};

4.Run Delegate Creation

1
2
3
CTRunDelegateRef __nullable CTRunDelegateCreate(
const CTRunDelegateCallbacks* callbacks,
void * __nullable refCon ) CT_AVAILABLE(10_5, 3_2);

5.Run Delegate Access

1
2
void * CTRunDelegateGetRefCon(
CTRunDelegateRef runDelegate ) CT_AVAILABLE(10_5, 3_2);

代码片段

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context , CGAffineTransformIdentity);
CGContextTranslateCTM(context , 0 ,self.bounds.size.height);
CGContextScaleCTM(context, 1.0 ,-1.0);
NSMutableAttributedString *mabstring = [[NSMutableAttributedString alloc]initWithString:@"富文本学习/慢慢来吧。不是一朝一夕之功。ok n ok ok"];
CTRunDelegateDeallocateCallback deallocateCallback= CTRunDelegateDeallocateCallbackFunction;
NSLog(@"CTRunDelegateGetAscentCallback 获取ascent");
CTRunDelegateGetAscentCallback ascentCallback= CTRunDelegateGetAscentCallbackFunction;
CTRunDelegateGetDescentCallback descentCallback = CTRunDelegateGetDescentCallbackFunction;
CTRunDelegateGetWidthCallback widthCallBack = CTRunDelegateGetWidthCallbackFunction;
CTRunDelegateCallbacks callBack ;
callBack.version =kCTRunDelegateCurrentVersion;
callBack.dealloc = deallocateCallback;
callBack.getAscent = ascentCallback;
callBack.getDescent = descentCallback;
callBack.getWidth = widthCallBack;
CTRunDelegateRef delegate= CTRunDelegateCreate(&callBack, NULL);
NSDictionary * dic =[NSDictionary dictionaryWithObject:(__bridge id)delegate forKey:(__bridge NSString * )kCTRunDelegateAttributeName];
unichar placeHolder = 0xFFFC;///占位符
NSString * placeHolderStr = [NSString stringWithCharacters:&placeHolder length:1];
NSAttributedString * att = [[NSAttributedString alloc]initWithString:placeHolderStr attributes:dic];
[mabstring insertAttributedString:att atIndex:3 ];
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)mabstring);
CGMutablePathRef Path = CGPathCreateMutable();
CGPathAddRect(Path, NULL ,CGRectMake(10 , 0 ,self.bounds.size.width-10 , self.bounds.size.height-60));
CFRange range = CFRangeMake(0, 0);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,range, Path, NULL);
CTFrameDraw(frame,context);
CGPathRelease(Path);
CFRelease(framesetter);
}

效果

image