2012-05-02 5 views

risposta

17

OK, quindi per tutti coloro che pensano un'iterazione non è evitabile:

NSString *string = @"The string to render"; 
CGRect rect = imageView.frame; 

UIFont *font = [UIFont fontWithSize:12.0]; // find the height of a 12.0pt font 
CGSize size = [string sizeWithFont:font]; 
float pointsPerPixel = 12.0/size.height; // compute the ratio 
// Alternatively: 
// float pixelsPerPoint = size.height/12.0; 
float desiredFontSize = rect.size.height * pointsPerPixel; 
// Alternatively: 
// float desiredFontSize = rect.size.height/pixelsPerPoint; 

desiredFontSize conterrà la dimensione del carattere in punti la cui altezza è esattamente la stessa come l'altezza del rettangolo specificato . Potresti volerlo moltiplicarlo, per esempio, per rendere il font un po 'più piccolo delle dimensioni effettive del rect per renderlo bello.

+0

Questo non sembra funzionare in modo affidabile - Ho iniziato una domanda separata [qui] (http://stackoverflow.com/questions/13663924/scaling-font-size-to-fit-vertically-in-uilabel). – user524261

+0

@ user524261 Buona domanda, +1 per quello. –

+0

Posso impostare la dimensione a 6,88 pt? –

1

Da qui

http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/CoreText_Programming/Operations/Operations.html

CGFloat GetLineHeightForFont(CTFontRef iFont) 
{ 
    CGFloat lineHeight = 0.0; 

    check(iFont != NULL); 

    // Get the ascent from the font, already scaled for the font's size 
    lineHeight += CTFontGetAscent(iFont); 

    // Get the descent from the font, already scaled for the font's size 
    lineHeight += CTFontGetDescent(iFont); 

    // Get the leading from the font, already scaled for the font's size 
    lineHeight += CTFontGetLeading(iFont); 

    return lineHeight; 
} 

Per utilizzare questa, indovinare una dimensione in punti, lo trovano è altezza della linea (che si può o non può preoccuparsi di primo piano). Quindi usa il rapporto tra la risposta e l'altezza che hai per ridimensionare la dimensione del punto. Non penso che tu abbia la certezza che l'altezza sarà esattamente giusta - se ti interessa che sia esatta, devi eseguire un'iterazione finché non è abbastanza vicina (usa la nuova dimensione come nuova ipotesi).

+0

Questo non risponde alla sua domanda. Sta cercando di ottenere la giusta dimensione per un font basato su un'altezza specifica, non capire quanto è alto un font. C'è anche una proprietà UIFont chiamata 'lineHeight' che quasi certamente ha la stessa identica implementazione. – mbm29414

+0

Ho aggiornato con informazioni su come utilizzare questo. –

+1

Perché non solo oggetti UIFont e chiamate '[font lineHeight]'? – mbm29414

0

Nota: Ciò presuppone che la dimensione del carattere sarà sempre inferiore alla dimensione in punti di CGRect. Regolare i metodi come necessario per correggere tale ipotesi.

Prova questo. Funziona per uno dei 3 metodi principali per creare un font. Dovrebbe essere abbastanza auto-esplicativo, ma l'incremento è l'importo che si desidera decrementare tra i controlli. Se non ti interessa il dimensionamento esatto, ingrandisci quel numero per una maggiore velocità. Se ti interessa, ridurlo per maggiore precisione.

- (UIFont *)systemFontForRectHeight:(CGFloat)height 
          increment:(CGFloat)increment { 

    UIFont *retVal = nil; 
    for (float i = height; i > 0; i = i - increment) { 
     retVal = [UIFont systemFontOfSize:i]; 
     if ([retVal lineHeight] < height) break; 
    } 
    return retVal; 
} 
- (UIFont *)boldSystemFontForRectHeight:(CGFloat)height 
           increment:(CGFloat)increment { 

    UIFont *retVal = nil; 
    for (float i = height; i > 0; i = i - increment) { 
     retVal = [UIFont boldSystemFontOfSize:i]; 
     if ([retVal lineHeight] < height) break; 
    } 
    return retVal; 
} 

- (UIFont *)fontNamed:(NSString *)name 
     forRectHeight:(CGFloat)height 
      increment:(CGFloat)increment { 

    UIFont *retVal = nil; 
    for (float i = height; i > 0; i = i - increment) { 
     retVal = [UIFont fontWithName:name size:i]; 
     if ([retVal lineHeight] < height) break; 
    } 
    return retVal; 
} 
+0

questo è estremamente inefficiente .. –

+0

Perché dici così? Inizia con un valore noto per essere vicino al valore finale desiderato (l'altezza del rettangolo) e consente all'utente di specificare la precisione desiderata per influenzare la velocità. Come lo faresti? – mbm29414

+0

Come l'altra risposta. Indovina una dimensione iniziale, quindi usa una divisione + moltiplicazione usando il rapporto trovato per calcolare la dimensione data.Questo è O (1), e dà una risposta che è sempre corretta, la tua è innecessariamente O (n) ed è probabile che non darà una risposta corretta se la dimensione del carattere desiderata non è un multiplo intero di 1pt. –

Problemi correlati