2015-03-13 18 views
14

Come posso impostare il colore di un'immagine basata su modello che è un allegato su una stringa attribuita?Come impostare il colore dell'immagine in formato NSTextAttachment

Background:

Ho un UILabel e sto impostando il suo attributedText a un NSAttributedString. NSAttributedString include un NSTextAttachment con una piccola immagine. Ora voglio fare in modo che il colore dell'immagine corrisponda al colore del testo e non riesco a capire come farlo funzionare.

Normalmente mi aspetto di colorare l'immagine impostando la sua modalità di rendering su UIImageRenderingModeAlwaysTemplate e quindi impostando tintColor sul UIView contenente. Ho provato a impostare tintColor sulla mia UILabel, ma ciò non ha alcun effetto.

Ecco il mio codice. E 'in Ruby (RubyMotion) quindi la sintassi potrebbe apparire un po' strano, ma le mappe 1: 1 con Objective C.

attachment = NSTextAttachment.alloc.initWithData(nil, ofType: nil) 
attachment.image = UIImage.imageNamed(icon_name).imageWithRenderingMode(UIImageRenderingModeAlwaysTemplate) 

label_string = NSMutableAttributedString.attributedStringWithAttachment(attachment) 
label_string.appendAttributedString(NSMutableAttributedString.alloc.initWithString('my text', attributes: { NSFontAttributeName => UIFont.preferredFontForTextStyle(UIFontTextStyleFootnote), NSForegroundColorAttributeName => foreground_color })) 

label = UILabel.alloc.initWithFrame(CGRectZero) 
label.tintColor = foreground_color 
label.attributedText = label_string 
label.textAlignment = NSTextAlignmentCenter 
label.numberOfLines = 0 
+0

Hai trovato qualche risposta a questo che non comporta il disegno dell'immagine prima di aggiungerla come allegato di testo? Mi piacerebbe avere un modo semplice per farlo. –

+0

Purtroppo no. Nel mio caso, avevo una stringa che a volte era bianca su uno sfondo scuro e talvolta nera su uno sfondo chiaro ... Alla fine ho solo cambiato l'immagine dell'allegato in un grigio neutro che funzionava su entrambi gli sfondi. – Ghazgkull

risposta

8

ho una buona esperienza con l'utilizzo della libreria UIImage+Additions quando colorazione UIImage di. Puoi trovarlo qui: https://github.com/vilanovi/UIImage-Additions. Controllare in particolare la sezione IV.

Se l'aggiunta di una libreria di terze parti non è un'opzione, qui è qualcosa per iniziare:

- (UIImage *)colorImage:(UIImage *)image color:(UIColor *)color 
{ 
    UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextTranslateCTM(context, 0, image.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); 

    CGContextSetBlendMode(context, kCGBlendModeNormal); 
    CGContextDrawImage(context, rect, image.CGImage); 
    CGContextSetBlendMode(context, kCGBlendModeSourceIn); 
    [color setFill]; 
    CGContextFillRect(context, rect); 


    UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return coloredImage; 
} 

Questo renderà un UIImage andare da: UIImage before tinting

Per

UIImage after tinting

+0

Grazie per il puntatore. Sperando di non dover introdurre un'intera nuova libreria per risolvere questo, però. – Ghazgkull

+0

@Ghazgkull Aggiunto un esempio di codice per iniziare. Fammi sapere di più su come vuoi tingere se questo non è come volevi farlo. –

+0

Normalmente tingere un'immagine semplicemente chiamando UIImage.imageWithRenderingMode (UIImageRenderingModeAlwaysTemplate) e quindi impostando il tintColor del UIView che lo contiene. Sono solo due righe di codice.L'unica ruga qui è che il mio UIImage si trova all'interno di una NSAttributedString, quindi non ho accesso all'immissione immediata di UIView che lo contiene. – Ghazgkull

22

Sembra che ci sia un bug in UIKit. C'è una soluzione alternativa per questo;]

Per qualche motivo è necessario aggiungere uno spazio vuoto prima dell'allegato dell'immagine per farlo funzionare correttamente con UIImageRenderingModeAlwaysTemplate.

Così il vostro frammento sarebbe simile a quello (il mio è in objC):

- (NSAttributedString *)attributedStringWithValue:(NSString *)string image:(UIImage *)image { 
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; 
    attachment.image = image; 

    NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; 
    NSMutableAttributedString *mutableAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[[NSAttributedString alloc] initWithString:@" "]]; 
    [mutableAttributedString appendAttributedString:attachmentString]; 
    [mutableAttributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:0] range:NSMakeRange(0, mutableAttributedString.length)]; // Put font size 0 to prevent offset 
    [mutableAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, mutableAttributedString.length)]; 
    [mutableAttributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@" "]]; 

    NSAttributedString *ratingText = [[NSAttributedString alloc] initWithString:string]; 
    [mutableAttributedString appendAttributedString:ratingText]; 
    return mutableAttributedString; 
} 
+0

Questo sembra essere il caso, e questa è un'informazione utile. Penso che andrò con l'approccio all'immagine tinta, ma è bello saperlo. –

+0

Ho trovato che 'NSForegroundColorAttributeName' non stava colorando l'immagine allegata. Invece lo prendeva dalla proprietà 'textColor' di' UILabel', anche se era sovrascritta nella stringa attribuita. – Samah

+1

È possibile utilizzare una stringa vuota anziché lo spazio, poiché lo spazio viene aggiunto al layout. [[NSMutableAttributedString alloc] initWithAttributedString: [[NSAttributoString alloc] initWithString: @ "\ 0"]]; – railwayparade

1

La soluzione da @blazejmar funziona, ma non è necessario. Tutto ciò che devi fare affinché questo funzioni è impostare il colore dopo che le stringhe attribuite sono state collegate. Ecco un esempio.

NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; 
attachment.image = [[UIImage imageNamed:@"ImageName"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 

NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; 

NSString *string = @"Some text "; 
NSRange range2 = NSMakeRange(string.length - 1, attachmentString.length); 

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string]; 
[attributedString appendAttributedString:attachmentString]; 
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range2]; 
self.label.attributedText = attributedString; 
-1

utilizzare UIImageRenderingModeAlwaysOriginal per il colore dell'immagine originale. UIImageRenderingModeAlwaysTemplate per colore personalizzato.