is this CoreText? - Aviary text pinch zoom expand
Asked Answered
F

1

6

I am looking into making an app where a user can change the size and orientation of UITextField. I was looking into Aviary app and what I see is that users can not only increase or decrease the size of the text but they can also change its orientation.

enter image description here

So the questions I want to ask are

1) Are they using CoreText to do this are they using just plain old UILabel or UIText?

2) I don't know how you can dynamically resize? Are they using UIView?

3) I have googled CoreText tutorials, examples, checked apple docs and sample projects, looked into cocoa controls and github and I still don't see any sample code or tutorial that will show how this is done.

Would anyone be kind enough to point me in some direction or a tutorial?

Flippant answered 16/4, 2013 at 13:23 Comment(0)
B
7

Regarding the appearance of the font, there are a couple of options:

  1. You can use the standard UILabel to achieve the most of the effects (font, size, color, rotation) you see here. The one feature that is beyond the standard UILabel is the white stroke around the font. But, effective iOS 6, you can also achieve the effect of the white stroke around the red text with a standard UILabel using its attributedText property, which is a NSAttributedString.

  2. In iOS versions prior to 6.0, to achieve the white stroke color around the text, you had to use CoreGraphics or CoreText.

Regarding the dynamic resizing, rotating, and moving of the text, they're undoubtedly just using gesture recognizers that adjust the transform property of the view (more accurately, probably adjusting transform for rotation, adjusting the center or frame for dragging, and adjusting both the frame and font size for resizing (if you just use scale transformation, you can end up with undesirable pixelation).

You'll get quite a few good hits if you search Stack Overflow for questions regarding gesture recognizers and dragging, resizing, and rotating of views.


In iOS 6, if you want the red text with a white border with a UILabel, you could do something like:

// create attributes dictionary

NSDictionary *attributes = @{
                             NSFontAttributeName            : [UIFont systemFontOfSize:48.0],
                             NSForegroundColorAttributeName : [UIColor redColor],
                             NSStrokeColorAttributeName     : [UIColor whiteColor],
                             NSStrokeWidthAttributeName     : @(-3)
                             };

// make the attributed string

NSAttributedString *stringToDraw = [[NSAttributedString alloc] initWithString:@"bigcat"
                                                                   attributes:attributes];

self.label.attributedText = stringToDraw;

For information about attributed strings in iOS, see:


If you need to support iOS versions prior to iOS 6, you have to use CoreText or CoreGraphics. A CoreText rendition might look like:

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    if (!self.text)
        return;

    // create a font

    CTFontRef sysUIFont = CTFontCreateUIFontForLanguage(kCTFontSystemFontType, self.fontSize, NULL);

    // create attributes dictionary

    NSDictionary *attributes = @{
                                 (__bridge id)kCTFontAttributeName            : (__bridge id)sysUIFont,
                                 (__bridge id)kCTForegroundColorAttributeName : (__bridge id)[self.fillColor CGColor],
                                 (__bridge id)kCTStrokeColorAttributeName     : (__bridge id)[self.borderColor CGColor],
                                 (__bridge id)kCTStrokeWidthAttributeName     : @(-3)
                                 };

    // make the attributed string

    NSAttributedString *stringToDraw = [[NSAttributedString alloc] initWithString:self.text
                                                                       attributes:attributes];

    // begin drawing

    CGContextRef context = UIGraphicsGetCurrentContext();

    // flip the coordinate system

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

    // create CTLineRef

    CTLineRef line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)stringToDraw);

    // figure out the size (which we'll use to center it)

    CGFloat ascent;
    CGFloat descent;
    CGFloat width = CTLineGetTypographicBounds(line, &ascent, &descent, NULL);
    CGFloat height = ascent + descent;
    CGSize stringSize = CGSizeMake(width, height);

    // draw it

    CGContextSetTextPosition(context,
                             (self.bounds.size.width  - stringSize.width)  / 2.0,
                             (self.bounds.size.height - stringSize.height + descent) / 2.0);
    CTLineDraw(line, context);

    // clean up

    CFRelease(line);
    CFRelease(sysUIFont);
}

A more complete implementation of the above can be found in my GitHub CoreText Demonstration.


Here is a very simple Core Graphics implementation of drawRect that writes text with a outline around the text:

@implementation CustomView

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    if (!self.text)
        return;

    // begin drawing

    CGContextRef context = UIGraphicsGetCurrentContext();

    // flip the coordinate system

    CGContextSetTextMatrix(context, CGAffineTransformMakeRotation(M_PI_4 / 2.0));
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    // write the text

    CGContextSelectFont (context, "Helvetica", self.fontSize, kCGEncodingMacRoman);
    CGContextSetTextDrawingMode (context, kCGTextFillStroke);
    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
    CGContextSetLineWidth(context, 1.5);
    CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextShowTextAtPoint (context, 40, 100, [self.text UTF8String], [self.text length]);
}

@end
Brent answered 16/4, 2013 at 14:21 Comment(7)
Hi Rob, I would like to emulate exactly what they are doing i.e. out line white border, rotate text etc. I understand core text maybe a bit challenging to work with but if I have the right tutorial or example to guide me I know this effect can be achieved. Unfortunately I have not come across a single sample project that can show me how this can be done. (googled for 2 days before posting a question here)Flippant
@SamBudda Some good tutorials include cocoanetics.com/2011/01/befriending-core-text and weblog.invasivecode.com/core-textBrent
I did google and looked into these two tutorials. I guess what I need is a tutorial / sample project on core text that shows how to draw a box around core text (as shown in the pic) and when I drag or increase or decrease it, how does the text also increases or decreases with in the box. I kind of know how to create core text, it just second part of the puzzle that I am struggling withFlippant
The drawing of the box around it is much easier than the text. It could be something as simple as a UIView with black background color, really low opacity/alpha. I might even be inclined to put the CoreGraphics/CoreText drawing into a custom UIView or UILayer subclass, so you could wrap the background and text in one nice object that could then be resized and dragged around.Brent
So the aviary app is using a combination of core graphics and core text?Flippant
@SamBudda - It could be using just CoreGraphics or it could be using CoreText. Impossible to tell from the screen snapshot. CoreText is far richer, but there's nothing here that necessitates it. Both would work fine, though.Brent
let us continue this discussion in chatFlippant

© 2022 - 2024 — McMap. All rights reserved.