Gostaria de anexar uma NSTextAttachment
imagem à minha string atribuída e centralizá-la verticalmente.
Usei o seguinte código para criar minha string:
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:DDLocalizedString(@"title.upcomingHotspots") attributes:attrs];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [[UIImage imageNamed:@"help.png"] imageScaledToFitSize:CGSizeMake(14.f, 14.f)];
cell.textLabel.attributedText = [str copy];
No entanto, a imagem parece estar alinhada com a parte superior da célula textLabel
.
Como posso alterar o retângulo no qual o anexo é desenhado?
ios
objective-c
swift
uilabel
nstextattachment
Sean Danzeiser
fonte
fonte
Respostas:
Você pode alterar o retângulo subclassificando
NSTextAttachment
e substituindoattachmentBoundsForTextContainer:proposedLineFragment:glyphPosition:characterIndex:
. Exemplo:Não é uma solução perfeita. Você tem que descobrir a origem Y “a olho” e se você alterar a fonte ou o tamanho do ícone, você provavelmente desejará alterar a origem Y. Mas não consegui encontrar uma maneira melhor, exceto colocando o ícone em uma exibição de imagem separada (que tem suas próprias desvantagens).
fonte
Você pode usar o capHeight da fonte.
Objective-C
Rápido
A imagem do anexo é renderizada na linha de base do texto. E o eixo y dele é invertido como o sistema de coordenadas gráfico principal. Se você quiser mover a imagem para cima, defina
bounds.origin.y
como positivo.A imagem deve ser alinhada verticalmente no centro com a capHeight do texto. Portanto, precisamos definir o
bounds.origin.y
para(capHeight - imageHeight)/2
.Para evitar algum efeito irregular na imagem, devemos arredondar a parte fração de y. Mas as fontes e as imagens geralmente são pequenas, mesmo 1px de diferença faz a imagem parecer desalinhada. Então, apliquei a função round antes de dividir. Isso torna a parte da fração do valor y .0 ou .5
No seu caso, a altura da imagem é maior do que capHeight da fonte. Mas você pode usar da mesma maneira. O valor do deslocamento y será negativo. E será definido abaixo da linha de base.
fonte
Experimente
- [NSTextAttachment bounds]
. Nenhuma subclasse necessária.Para o contexto, estou renderizando um
UILabel
para uso como imagem de anexo e, em seguida, definindo os limites da seguinte forma:attachment.bounds = CGRectMake(0, self.font.descender, attachment.image.size.width, attachment.image.size.height)
e linhas de base do texto dentro da imagem do rótulo e do texto na linha de string atribuída conforme desejado.fonte
attachment.bounds = CGRect(x: 0.0, y: self.font.descender, width: attachment.image!.size.width, height: attachment.image!.size.height)
descender
propriedade da UIFont!Eu encontrei uma solução perfeita para isso, funciona como um encanto para mim, no entanto, você tem que experimentar (provavelmente a constante depende da resolução do dispositivo e talvez o que quer que seja;)
Deve funcionar e não deve ficar borrado de nenhuma forma (graças a
CGRectIntegral
)fonte
A respeito:
Nenhuma subclasse necessária
fonte
@Travis está correto ao afirmar que o deslocamento é o descendente da fonte. Se você também precisar dimensionar a imagem, você precisará usar uma subclasse de NSTextAttachment. Abaixo está o código, que foi inspirado neste artigo . Eu também postei como uma essência .
Use da seguinte maneira:
fonte
Se você tem um ascendente muito grande e deseja centralizar a imagem (centro da altura da tampa) como eu, tente isto
O cálculo de y é como a imagem abaixo
Observe que o valor de y é 0 porque queremos que a imagem se desloque para baixo da origem
Se você quiser que ele fique no meio de todo o rótulo. Use este valor y:
fonte
Podemos fazer uma extensão no swift 4 que gere um anexo com uma imagem centralizada como esta:
Então você pode fazer a ligação enviando o nome da imagem e da fonte:
E, em seguida, anexe o imageAttachment ao attributeString
fonte
No meu caso, chamar sizeToFit () ajudou. In swift 5.1
Dentro do seu rótulo personalizado:
fonte
Use -lineFrag.size.height / 5.0 para a altura dos limites. Centraliza exatamente a imagem e alinha com o texto para todos os tamanhos de fontes
fonte
-lineFrag.size.height/5.0
não está correto. Em vez disso, é o descensor da fonte.