Tudo que eu quero é uma borda preta de um pixel ao redor do meu texto UILabel branco.
Cheguei ao ponto de criar uma subclasse de UILabel com o código abaixo, que remontei desajeitadamente a partir de alguns exemplos online tangencialmente relacionados. E funciona, mas é muito, muito lento (exceto no simulador) e também não consegui centralizar o texto verticalmente (por isso codifiquei o valor y na última linha temporariamente). Ahhhh!
void ShowStringCentered(CGContextRef gc, float x, float y, const char *str) {
CGContextSetTextDrawingMode(gc, kCGTextInvisible);
CGContextShowTextAtPoint(gc, 0, 0, str, strlen(str));
CGPoint pt = CGContextGetTextPosition(gc);
CGContextSetTextDrawingMode(gc, kCGTextFillStroke);
CGContextShowTextAtPoint(gc, x - pt.x / 2, y, str, strlen(str));
}
- (void)drawRect:(CGRect)rect{
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGRect viewBounds = self.bounds;
CGContextTranslateCTM(theContext, 0, viewBounds.size.height);
CGContextScaleCTM(theContext, 1, -1);
CGContextSelectFont (theContext, "Helvetica", viewBounds.size.height, kCGEncodingMacRoman);
CGContextSetRGBFillColor (theContext, 1, 1, 1, 1);
CGContextSetRGBStrokeColor (theContext, 0, 0, 0, 1);
CGContextSetLineWidth(theContext, 1.0);
ShowStringCentered(theContext, rect.size.width / 2.0, 12, [[self text] cStringUsingEncoding:NSASCIIStringEncoding]);
}
Tenho apenas a sensação incômoda de estar negligenciando uma maneira mais simples de fazer isso. Talvez substituindo "drawTextInRect", mas não consigo fazer drawTextInRect se curvar à minha vontade, apesar de olhá-lo atentamente e franzir a testa com muita força.
ios
objective-c
iphone
cocoa-touch
core-graphics
Monte Hurd
fonte
fonte
Respostas:
Consegui fazer isso substituindo drawTextInRect:
fonte
UILabel
e colocar a-drawTextInRect:
implementação lá.Uma solução mais simples é usar uma string atribuída da seguinte forma:
Swift 4:
Swift 4.2:
Em a,
UITextField
você pode definir odefaultTextAttributes
e oattributedPlaceholder
também.Observe que o
NSStrokeWidthAttributeName
deve ser negativo neste caso, ou seja, apenas os contornos internos funcionam.fonte
Depois de ler a resposta aceita e as duas correções para ela e a resposta de Axel Guilmin, decidi compilar uma solução global em Swift, que me convém:
Você pode adicionar esta classe UILabel personalizada a um rótulo existente no Interface Builder e alterar a espessura da borda e sua cor adicionando Atributos de Tempo de Execução Definidos pelo Usuário como este:
Resultado:
fonte
Há um problema com a implementação da resposta. Desenhar um texto com traço tem uma largura de glifo de caractere ligeiramente diferente do desenho de um texto sem traço, o que pode produzir resultados "descentrados". Ele pode ser corrigido adicionando um traço invisível ao redor do texto de preenchimento.
Substituir:
com:
Não tenho 100% de certeza, se esse é o negócio real, porque não sei se
self.textColor = textColor;
tem o mesmo efeito que[textColor setFill]
, mas deve funcionar.Divulgação: Sou o desenvolvedor do THLabel.
Eu lancei uma subclasse UILabel um tempo atrás, que permite um contorno no texto e outros efeitos. Você pode encontrá-lo aqui: https://github.com/tobihagemann/THLabel
fonte
Isso não criará um contorno em si, mas colocará uma sombra ao redor do texto e, se você tornar o raio da sombra pequeno o suficiente, ele poderá se parecer com um contorno.
Não sei se é compatível com versões anteriores do iOS.
Enfim, espero que ajude ...
fonte
Uma versão da classe Swift 4 baseada na resposta de kprevas
Ele pode ser implementado inteiramente no Interface Builder, definindo a classe personalizada do UILabel como OutlinedText. Você então poderá definir a largura e a cor do contorno no painel Propriedades.
fonte
Se você quiser animar algo complicado, a melhor maneira é fazer uma captura de tela programática e animar isso!
Para fazer uma captura de tela de uma visualização, você precisará de um código um pouco como este:
Onde mainContentView é a visualização da qual você deseja fazer uma captura de tela. Adicione viewImage a um UIImageView e anime-o.
Espero que isso acelere sua animação !!
N
fonte
Como MuscleRumble mencionou, a fronteira da resposta aceita está um pouco fora do centro. Consegui corrigir isso definindo a largura do traço como zero em vez de mudar a cor para transparente.
ou seja, substituindo:
com:
Eu teria apenas comentado sobre sua resposta, mas aparentemente não sou "respeitável" o suficiente.
fonte
se TUDO o que você quer é uma borda preta de um pixel ao redor do meu texto UILabel branco,
então eu acho que você está tornando o problema mais difícil do que é ... Não sei de memória qual função 'draw rect / frameRect' você deve usar, mas será fácil para você encontrar. este método apenas demonstra a estratégia (deixe a superclasse fazer o trabalho!):
fonte
Encontrei um problema com a resposta principal. A posição do texto não é necessariamente centralizada corretamente na localização de subpixel, de modo que o contorno pode não corresponder ao texto. Eu corrigi usando o seguinte código, que usa
CGContextSetShouldSubpixelQuantizeFonts(ctx, false)
:Isso pressupõe que você definiu
textOutlineColor
etextOutlineWidth
como propriedades.fonte
Aqui está outra resposta para definir o texto delineado no rótulo.
definir texto delineado simplesmente usando o método de extensão.
fonte
também é possível criar uma subclasse de UILabel com a seguinte lógica:
e se você definir o texto no Storyboard, então:
fonte
Se sua meta for algo assim:
Aqui está como eu consegui isso: Eu adicionei uma nova
label
classe personalizada como uma subvisualização ao meu UILabel atual (inspirado por esta resposta ).Basta copiar e colar em seu projeto e você estará pronto para prosseguir:
USO:
também funciona para um
UIButton
com todas as suas animações:fonte
Por que você não cria um UIView de borda de 1px no Photoshop, em seguida define um UIView com a imagem e posiciona-o atrás do UILabel?
Código:
Isso vai economizar a criação de subclasses de um objeto e é bastante simples de fazer.
Sem mencionar que se você deseja fazer animação, ela está embutida na classe UIView.
fonte
Para colocar uma borda com bordas arredondadas em torno de um UILabel, faço o seguinte:
(não se esqueça de incluir QuartzCore / QuartzCore.h)
fonte