- (void)drawRect:(CGRect)rect { // Drawing code // Initialize a graphics context in iOS. CGContextRef context = UIGraphicsGetCurrentContext(); // Flip the context coordinates, in iOS only. CGContextTranslateCTM(context, 0, self.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); // Set the text matrix. CGContextSetTextMatrix(context, CGAffineTransformIdentity); // Create a path which bounds the area where you will be drawing text. // The path need not be rectangular. CGMutablePathRef path = CGPathCreateMutable(); // In this simple example, initialize a rectangular path. CGRect bounds = CGRectMake(10.0,rect.size.height - 300.0, 200.0, 200.0); CGPathAddRect(path, NULL, bounds ); // Initialize a string. CFStringRef textString = CFSTR("Hello, World! I know nothing in the world that has as much power as a word. Sometimes I write one, and I look at it, until it begins to shine."); // Create a mutable attributed string with a max length of 0. // The max length is a hint as to how much internal storage to reserve. // 0 means no hint. CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0); // Copy the textString into the newly created attrString CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), textString); // Create a color that will be added as an attribute to the attrString. // 字体颜色设置. CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), kCTForegroundColorAttributeName, [UIColor redColor].CGColor); // 大小设置 CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), kCTFontAttributeName, (__bridge CFTypeRef)([UIFont boldSystemFontOfSize:18])); // 下划线设置 /*** kCTUnderlineStyleNone = 0x00, kCTUnderlineStyleSingle = 0x01, kCTUnderlineStyleThick = 0x02, kCTUnderlineStyleDouble = 0x09 ****/ CFAttributedStringSetAttribute(attrString, CFRangeMake(12, 24), kCTUnderlineColorAttributeName, [UIColor greenColor].CGColor); CFAttributedStringSetAttribute(attrString, CFRangeMake(12, 24), kCTUnderlineStyleAttributeName, (__bridge CFTypeRef)[NSNumber numberWithInt:kCTUnderlineStyleSingle]); // 字与字水平垂直间距调整 CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), kCTKernAttributeName, (__bridge CFTypeRef)[NSNumber numberWithInt:5]); CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), kCTSuperscriptAttributeName, (__bridge CFTypeRef)[NSNumber numberWithInt:5]); // 背景颜色设置 CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), kCTBackgroundColorAttributeName, [UIColor grayColor].CGColor); // Create the framesetter with the attributed string. CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString); CFRelease(attrString); // Create a frame. CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); // Draw the specified frame in the given context. CTFrameDraw(frame, context); // Release the objects we used. CFRelease(frame); CFRelease(path); CFRelease(framesetter); }
- (void)drawRect:(CGRect)rect { // Drawing code // Initialize a graphics context in iOS. CGContextRef context = UIGraphicsGetCurrentContext(); // Flip the context coordinates in iOS only. CGContextTranslateCTM(context, 0, self.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); // Set the text matrix. CGContextSetTextMatrix(context, CGAffineTransformIdentity); NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:@"Hello, World! I know nothing in the world that has as much power as a word. Sometimes I write one, and I look at it, until it begins to shine."]; // Create the framesetter with the attributed string. CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); // Call createColumnsWithColumnCount function to create an array of // three paths (columns). CFArrayRef columnPaths = [self createColumnsWithColumnCount:3]; CFIndex pathCount = CFArrayGetCount(columnPaths); CFIndex startIndex = 0; int column; // Create a frame for each column (path). for (column = 0; column < pathCount; column++) { // Get the path for this column. CGPathRef path = (CGPathRef)CFArrayGetValueAtIndex(columnPaths, column); // Create a frame for this column and draw it. CTFrameRef frame = CTFramesetterCreateFrame( framesetter, CFRangeMake(startIndex, 0), path, NULL); CTFrameDraw(frame, context); // Start the next frame at the first character not visible in this frame. CFRange frameRange = CTFrameGetVisibleStringRange(frame); startIndex += frameRange.length; CFRelease(frame); } CFRelease(columnPaths); CFRelease(framesetter); } - (CFArrayRef)createColumnsWithColumnCount:(int)columnCount { int column; CGRect* columnRects = (CGRect*)calloc(columnCount, sizeof(*columnRects)); // Set the first column to cover the entire view. columnRects[0] = self.bounds; // Divide the columns equally across the frame's width. CGFloat columnWidth = CGRectGetWidth(self.bounds) / columnCount; for (column = 0; column < columnCount - 1; column++) { CGRectDivide(columnRects[column], &columnRects[column], &columnRects[column + 1], columnWidth, CGRectMinXEdge); } // Inset all columns by a few pixels of margin. for (column = 0; column < columnCount; column++) { columnRects[column] = CGRectInset(columnRects[column], 8.0, 15.0); } // Create an array of layout paths, one for each column. CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, columnCount, &kCFTypeArrayCallBacks); for (column = 0; column < columnCount; column++) { CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, columnRects[column]); CFArrayInsertValueAtIndex(array, column, path); CFRelease(path); } free(columnRects); return array; }