Monday, June 13, 2011

CoreText Tutorial - Part 2

You can access Part 1 HERE


In Part 2, We will see how we get to have the different kinds of underlined strings.

    /* We are going to create a text label with  various kinds of underlines */
    
    //Create our context
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    
    //Flip the context so that the text will appear right , 
    //otherwise it appears upside down and its mirror image.
    CGAffineTransform flipTransform = CGAffineTransformMake( 1, 0, 0, -1, 0, self.frame.size.height);
    CGContextConcatCTM(context, flipTransform);
    

    //Fill the context bg with white
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillRect(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height));
    
    //This is the string we want to write on our screen and we also need to get the string length
    NSString *test = @"We hold this truth to be self-evident, that everyone is created equal.And everybody deserves a second chance.";
    NSInteger _stringLength=[test length];
    
    
    //Convert NSString to CFStringRef
    // Initialize an attributed string.
    //Copy the CFStringRef to CFMutableAttributedStringRef
    CFStringRef string =  (CFStringRef) test;
    CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
    CFAttributedStringReplaceString (attrString,CFRangeMake(0, 0), string);
    
    /*
     Note: we could have created CFAttributedStringRef which is non mutable, then we would have to give all its
     attributes right when we create it. We can change them if we use mutable form of CFAttributeString.
     
     Note: Like kCTForegroundColorAttributeName , kCTFontAttributeName we have many more attributes of CFAttributeString which can be set by us and making out string look really cool. We will check them out later on. 
     */

    

    
    CGColorRef _red=[UIColor redColor].CGColor;
    CGColorRef _blue=[UIColor blueColor].CGColor;    
    
    //Lets have our string  as red 
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTForegroundColorAttributeName, _red);    
    
    
    //Now lets make the font more bigger than normal
    //I dont know whats the default size but its very small like 12.0f Helvetica
    //So you set attribute called kCTFontAttributeName
    CTFontRef font = CTFontCreateWithName((CFStringRef)@"GillSans", 20.0f, nil);
    CFAttributedStringSetAttribute(attrString,CFRangeMake(0, _stringLength),kCTFontAttributeName,font);
    
    //Lets do some underlining with blue color
    SInt32 type = kCTUnderlineStyleSingle;
    CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type, &type);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);
    
    
    // Initialize a rectangular path.
    CGMutablePathRef path = CGPathCreateMutable();
    CGRect bounds = CGRectMake(10.0, 10.0, 200.0, 200.0);
    CGPathAddRect(path, NULL, bounds);
    
    
    // Create the framesetter with the attributed string.
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
    CFRelease(attrString);
    
    // Create the frame and draw it into the graphics context
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0, 0), path, NULL);
    CFRelease(framesetter);
    CTFrameDraw(frame, context);


Whole magic is done by following 3 lines of the code



SInt32 type = kCTUnderlineStyleSingle;
    CFNumberRef underline = CFNumberCreate(NULLkCFNumberSInt32Type, &type);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);



This is what the output looks like.












-----------------------------------------------------------------------------------------------------------------------------
If we change the above 3 lines to following, you will have different kind of look. You can always decide till what character index you want to have your string underlined. So if you want to have only first 10 characters underlined, you will CFRangeMake as CFRangeMake(0,10) and if you want complete string underlined then CFRangeMake(0, stringlength).





 SInt32 one = kCTUnderlineStyleSingle | kCTUnderlinePatternDot;
    CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type,&one);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);


















-----------------------------------------------------------------------------------------------------------------------------









 SInt32 one = kCTUnderlineStyleDouble|kCTUnderlinePatternDot;
    CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type,&one);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);
    





























-----------------------------------------------------------------------------------------------------------------------------






    SInt32 one = kCTUnderlineStyleSingle|kCTUnderlinePatternDash;
    CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type,&one);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);
    
































-----------------------------------------------------------------------------------------------------------------------------







SInt32 one = kCTUnderlineStyleSingle|kCTUnderlinePatternDashDot;
    CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type,&one);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);
    
    


























-----------------------------------------------------------------------------------------------------------------------------





 SInt32 one = kCTUnderlineStyleSingle|kCTUnderlinePatternDashDotDot;
    CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type,&one);  
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineStyleAttributeName, underline);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, _stringLength),kCTUnderlineColorAttributeName, _blue);
    
    
    



















-----------------------------------------------------------------------------------------------------------------------------



Basically, you can use any combination of

 kCTUnderlineStyleNone
kCTUnderlineStyleSingle  
kCTUnderlineStyleThick  
kCTUnderlineStyleDouble  


AND 

 kCTUnderlinePatternSolid  
kCTUnderlinePatternDot
kCTUnderlinePatternDash  
kCTUnderlinePatternDashDot
kCTUnderlinePatternDashDotDot







Hope it helps !







No comments:

Post a Comment