2

Framing this question as directly and with as much information as possible, so as to allow a definitive answer. There's even a picture!

I have a simple subclass of UILabel (subclassed to allow rendering of stroked text).

Header:

//  svCustomNumeralLabel.h

#import <UIKit/UIKit.h>

@interface svCustomNumeralLabel : UILabel

@property UIFont *customFont;
@property CGPoint drawPoint;

@end

Complete implementation:

#import "svCustomNumeralLabel.h"

@implementation svCustomNumeralLabel

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialize];
    }
    return self;
}


-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initialize];
    }
    return self;
}


-(void)initialize{
    self.customFont =  [UIFont fontWithName:@"Forgotten Futurist" size:200.0];
    self.drawPoint = CGPointMake(-10.0,-39.0);

    float capHeight = self.customFont.capHeight;
    NSLog(@"Cap height: %f", capHeight);
}


- (void)drawRect:(CGRect)rect
{

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);//RGBA
    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
    CGContextSetTextDrawingMode(context, kCGTextFillStroke);

    float descender = self.customFont.descender;
    float ascender = self.customFont.ascender;

    NSLog(@"Ascender: %f descender: %f", ascender, descender);

    CGSize frameSize = self.frame.size;
    NSLog(@"Frame width: %f height: %f", frameSize.width, frameSize.height);

    CGSize unDrawnSize = [self.text sizeWithFont:self.customFont];
    NSLog(@"Undrawn width: %f height: %f", unDrawnSize.width, unDrawnSize.height);

    CGSize drawnSize = [self.text drawAtPoint:self.drawPoint withFont:self.customFont];
    NSLog(@"Drawn width: %f height: %f", drawnSize.width, drawnSize.height);

}

I've put an instance of this class into a UIView in Interface Builder. The svCustomNumeralLabel's view has been manually sized in IB to 80.0 width, 127.0 height.

I've set the value of self.drawPoint in the initialize() method by trial-and-error, to its current value of (-10.0, -39.0).

The result, with these manually set and hard-wired values, is a nice numeral, exactly positioned within its container frame (which for clarity is set to have a gray background):svCustomNumeralLabel screengrab

The NSLog output from the run above:

Cap height: 126.600006
Ascender: 165.601562 descender: -58.400002
Frame width: 80.000000 height: 127.000000
Undrawn width: 100.000000 height: 229.000000
Drawn width: 99.200005 height: 229.000000

My question

How could I have programmatically determined the value of self.drawPoint to achieve this result, ie the '0' character rendered at the exact top-left?

Secondary question: how can I compute a correct value for the precise width and height of the character, as actually rendered, to facilitate fitting it nice and snug in its view?

As you can see from the NSLog outputs, there appears to be very little information available that bears much resemblance to the actual numeral as drawn. The only metric that correlates with frame dimensions is UIFont.capHeight. There appears to be no information that I could reliably use to determine the (-10.0, -39.0) offset value of self.drawPoint.

4

2 回答 2

0

AppKit 为 Foundation Framework 提供了一些不错的补充NSStringNSString UIKit Additions

特别感兴趣:- (CGSize)sizeWithFont:(UIFont *)font和相关的方法。

于 2013-04-16T18:36:07.237 回答