web-dev-qa-db-fra.com

Ombre portée sur le texte UITextField

Est-il possible d'ajouter une ombre au texte dans un UITextField?

54
DotSlashSlash

Depuis la version 3.2, vous pouvez utiliser les propriétés de l'ombre CALayer.

_textField.layer.shadowOpacity = 1.0;   
_textField.layer.shadowRadius = 0.0;
_textField.layer.shadowColor = [UIColor blackColor].CGColor;
_textField.layer.shadowOffset = CGSizeMake(0.0, -1.0);
176
egarc

J'ai un problème légèrement différent - je veux une ombre floue sur un UILabel. Heureusement, la solution à cela s'est avérée être le numéro (2) de Tyler

Voici mon code:

- (void) drawTextInRect:(CGRect)rect {
    CGSize myShadowOffset = CGSizeMake(4, -4);
    CGFloat myColorValues[] = {0, 0, 0, .8};

    CGContextRef myContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(myContext);

    CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB();
    CGColorRef myColor = CGColorCreate(myColorSpace, myColorValues);
    CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);

    [super drawTextInRect:rect];

    CGColorRelease(myColor);
    CGColorSpaceRelease(myColorSpace); 

    CGContextRestoreGState(myContext);
}

C'est dans une classe qui s'étend de UILabel et dessine le texte avec une ombre vers le bas et vers la droite 4px, l'ombre est grise à 80% d'opacité et est visiblement floue.

Je pense que la solution Tyler numéro 2 est un peu meilleure pour les performances que Tyler numéro 1 - vous ne traitez qu'avec un seul UILabel dans la vue et, en supposant que vous ne redessinez pas chaque image, ce n'est pas un succès dans le rendu des performances sur un UILabel normal.

PS Ce code emprunté fortement à la documentation Quartz 2D

72
deanWombourne

Je ne pense pas que vous bénéficiez d'un support intégré pour les ombres de texte ici, comme vous le faites avec UILabel.

Deux idées:

(1) [Modérément délicat à coder.] Ajoutez un deuxième UITextField derrière l'original, avec un très petit décalage (peut-être de (0,2,0,8)?). Vous pouvez écouter chaque changement de texte clé par clé en implémentant le textField:shouldChangeCharactersInRange:replacementString: méthode dans le protocole UITextFieldDelegate . En utilisant cela, vous pouvez mettre à jour le texte inférieur simultanément. Vous pouvez également rendre le texte inférieur (le texte d'ombre) gris et même légèrement flou en utilisant le fait que le texte partiellement décalé apparaît flou. Ajouté: Oh oui, n'oubliez pas de définir la couleur d'arrière-plan du champ de texte supérieur sur [UIColor clearColor] si vous allez avec cette idée.

(2) [Encore plus de plaisir à coder.] Sous-classe UITextField et remplacez le drawRect: méthode. Je ne l'ai pas fait auparavant, je vais donc mentionner à l'avance que cela dépend de la méthode de dessin désignée, et il peut s'avérer que vous devez remplacer une autre fonction de dessin, telle que drawTextInRect: , qui est spécifique à UITextField. Maintenant, configurez le contexte de dessin pour dessiner des ombres via les fonctions CGContextSetShadow , et appelez [super drawRect:rect];. J'espère que cela fonctionne - dans le cas où le code UITextField d'origine efface les paramètres d'ombre du contexte de dessin, cette idée est traitée, et vous devrez écrire vous-même le code de dessin entier, ce que je déconseille en raison de tous les extras qui viennent avec UITextFields comme copier-coller et kanji en japonais.

19
Tyler

Bien que la méthode d'application directe de l'ombre au UITextView fonctionne, ce n'est pas la bonne façon de procéder. En ajoutant l'ombre directement avec une couleur d'arrière-plan claire, toutes les sous-vues obtiendront l'ombre, même le curseur.

L'approche qui devrait être utilisée est avec NSAttributedString.

NSMutableAttributedString* attString = [[NSMutableAttributedString alloc] initWithString:textView.text];
NSRange range = NSMakeRange(0, [attString length]);

[attString addAttribute:NSFontAttributeName value:textView.font range:range];
[attString addAttribute:NSForegroundColorAttributeName value:textView.textColor range:range];

NSShadow* shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor whiteColor];
shadow.shadowOffset = CGSizeMake(0.0f, 1.0f);
[attString addAttribute:NSShadowAttributeName value:shadow range:range];

textView.attributedText = attString;

Cependant textView.attributedText est pour iOS6. Si vous devez prendre en charge des versions inférieures, vous pouvez utiliser l'approche suivante. (N'oubliez pas d'ajouter #import <QuartzCore/QuartzCore.h>)

CALayer *textLayer = (CALayer *)[textView.layer.sublayers objectAtIndex:0];
textLayer.shadowColor = [UIColor whiteColor].CGColor;
textLayer.shadowOffset = CGSizeMake(0.0f, 1.0f);
textLayer.shadowOpacity = 1.0f;
textLayer.shadowRadius = 0.0f;
16
cnotethegr8