Estou pesquisando há horas, mas falhei. Provavelmente nem sei o que devo procurar.
Muitos aplicativos têm texto e, neste texto, são hiperlinks da Web em formato arredondado. Quando clico nelas, é UIWebView
aberto. O que me intriga é que eles geralmente têm links personalizados, por exemplo, se as palavras começam com #, também é clicável e o aplicativo responde abrindo outra visualização. Como eu posso fazer isso? É possível UILabel
ou preciso UITextView
ou algo mais?
Swift 4
solução totalmente funcional . Ele usa,UITextView
mas faz com que se comporte como umUILabel
. Tentei as soluções aqui e não obtive a detecção precisa do link.Respostas:
Em geral, se quisermos ter um link clicável no texto exibido pelo UILabel, precisaremos resolver duas tarefas independentes:
O primeiro é fácil. A partir do iOS 6, o UILabel suporta a exibição de strings atribuídas. Tudo que você precisa fazer é criar e configurar uma instância do NSMutableAttributedString:
É isso aí! O código acima faz com que o UILabel exiba String com um link
Agora devemos detectar toques neste link. A idéia é capturar todos os toques no UILabel e descobrir se o local do toque estava próximo o suficiente do link. Para capturar toques, podemos adicionar o reconhecedor de gestos ao toque. Certifique-se de ativar userInteraction para o rótulo, pois está desativado por padrão:
Agora, o mais sofisticado: descobrir se a torneira estava onde o link é exibido e não em qualquer outra parte do rótulo. Se tivéssemos o UILabel de linha única, essa tarefa poderia ser resolvida de maneira relativamente fácil, codificando os limites da área em que o link é exibido, mas vamos resolver esse problema de maneira mais elegante e, para casos gerais - UILabel de várias linhas sem conhecimento preliminar sobre o layout do link.
Uma das abordagens é usar os recursos da API do kit de texto introduzidos no iOS 7:
Salve instâncias criadas e configuradas do NSLayoutManager, NSTextContainer e NSTextStorage nas propriedades da sua classe (provavelmente descendente do UIViewController) - precisaremos delas em outros métodos.
Agora, sempre que o rótulo alterar seu quadro, atualize o tamanho do textContainer:
E, finalmente, detecte se a torneira estava exatamente no link:
fonte
cellForRowAtIndexPath
? Também estou criando e configurando instânciascellForRowAtIndexPath
e hospedando ahandleTapOnLabel
função. Mas àscell.textLabel.addGestureRecognizer(UITapGestureRecognizer(target: cell, action: "handleTapOnLabel:"))
, eu estou recebendounrecognized selector
.textAlignment
atributo do rótulo esteja definido comoNSTextAlignmentCenter
. Se você estiver usando texto não centralizado, será necessário ajustar o cálculotextContainerOffset
no código acima.x
valor detextContainerOffset
, a constante0.5
é usada. Isso calculará a posição correta paraNSTextAlignmentCenter
. Para alinhar à esquerda, natural ou justificado, use o valor de0.0
. Para alinhar à direita, use1.0
.Estou estendendo a solução detalhada original do @NAlexN , com a excelente extensão do @zekel
UITapGestureRecognizer
e fornecendo no Swift .Estendendo UITapGestureRecognizer
Uso
Configure
UIGestureRecognizer
para enviar açõestapLabel:
e você poderá detectar se os intervalos de destino estão sendo aproveitadosmyLabel
.IMPORTANTE: O
UILabel
modo de quebra de linha deve ser definido para quebrar por palavra / caractere. De alguma forma,NSTextContainer
assumirá que o texto é de linha única apenas se o modo de quebra de linha for diferente.fonte
targetRange1
etargetRange2
.NSMutableAttributedString(attributedString: text)
onde 'texto' é umNSAttributedString
Pergunta antiga, mas se alguém pode usar um em
UITextView
vez de umUILabel
, é fácil. URLs padrão, números de telefone etc. serão detectados automaticamente (e clicáveis).No entanto, se você precisar de detecção personalizada, ou seja, se desejar chamar qualquer método personalizado depois que um usuário clicar em uma palavra específica, será necessário usar
NSAttributedStrings
umNSLinkAttributeName
atributo que aponte para um esquema de URL personalizado (em vez de ter o esquema de URL http por padrão). Ray Wenderlich tem aquiCitando o código do link mencionado acima:
Para detectar esses cliques no link, implemente isto:
PS: Verifique se você
UITextView
éselectable
.fonte
O UIButtonTypeCustom é um rótulo clicável se você não definir nenhuma imagem para ele.
fonte
(Minha resposta baseia-se na excelente resposta do @ NAlexN . Não vou duplicar sua explicação detalhada de cada etapa aqui.)
Achei mais conveniente e direto adicionar suporte ao texto UILabel com capacidade de tocar como uma categoria no UITapGestureRecognizer. (Você não precisa usar os detectores de dados do UITextView, como sugerem algumas respostas.)
Adicione o seguinte método à sua categoria UITapGestureRecognizer:
Código de exemplo
Gesto de retorno de chamada
fonte
plainText.length
.UITapGestureRecognizer
. Aqui estão algumas informações sobre como adicionar categorias.UITextView
suporta detectores de dados no OS3.0, enquantoUILabel
não.Se você ativar os detectores de dados no
UITextView
e seu texto contiver URLs, números de telefone etc., eles aparecerão como links.fonte
hashtag://
ou algo assim e use-otextView(_:shouldInteractWith:in:interaction:)
para detectá-lo. Veja a resposta abaixo: stackoverflow.com/a/34014655/1161906Traduzindo a extensão de @ samwize para Swift 4:
Para configurar o reconhecedor (depois de colorir o texto e outras coisas):
... então o reconhecedor de gestos:
fonte
didTapAttributedTextInLabel
precisa de umNSRange
argumento, masrangeTerms
retorna algo diferente. Além disso, ahandleTapOnLabel
função deve ser marcada com@objc
a Swift 4.Como mencionei neste post , aqui está uma biblioteca leve que eu criei especialmente para links no UILabel FRHyperLabel .
Para obter um efeito como este:
Lorem ipsum dolor sente-se no meio, consectetur elip adipiscing. Pellentesque quis blandit eros, sente-se entre veículos justos. Nam na urna neque. Mecânicas ac sem eu dictum porta nec vel tellus.
use o código:
fonte
Criei a subclasse UILabel denominada ResponsiveLabel, que é baseada na API do kit de texto introduzida no iOS 7. Ele usa a mesma abordagem sugerida pelo NAlexN . Ele fornece flexibilidade para especificar um padrão para pesquisar no texto. Pode-se especificar estilos a serem aplicados a esses padrões, bem como ações a serem executadas ao tocar nos padrões.
Se você deseja tornar uma sequência clicável, é possível fazer isso. Este código aplica atributos a cada ocorrência da cadeia "texto".
fonte
Trabalhou no Swift 3, colando todo o código aqui
fonte
Aqui está um código de exemplo para vincular o UILabel: Fonte: http://sickprogrammersarea.blogspot.in/2014/03/adding-links-to-uilabel.html
fonte
Aqui está uma versão rápida da resposta do NAlexN.
Você pode criar uma instância dessa classe dentro do seu
viewDidLoad
método como este:É melhor ter um atributo personalizado para usar quando um caractere é tocado. Agora, é
NSLinkAttributeName
, mas pode ser qualquer coisa e você pode usar esse valor para fazer outras coisas além de abrir um URL, você pode executar qualquer ação personalizada.fonte
Eu tive dificuldade em lidar com isso ... UILabel com links no texto atribuído ... é apenas uma dor de cabeça, então acabei usando o ZSWTappableLabel .
fonte
Como é relatado na resposta anterior, o UITextView é capaz de lidar com toques nos links. Isso pode ser facilmente estendido, fazendo com que outras partes do texto funcionem como links. A biblioteca AttributedTextView é uma subclasse UITextView que facilita muito o tratamento deles. Para mais informações, consulte: https://github.com/evermeer/AttributedTextView
Você pode fazer qualquer parte do texto interagir dessa maneira (em que textView1 é um UITextView IBOutlet):
E para lidar com hashtags e menções, você pode usar código como este:
fonte
Estou estendendo a resposta do @ samwize para manipular UILabel de várias linhas e dar um exemplo de como usar um UIButton
fonte
Eu sigo esta versão,
Swift 4:
Exemplo de chamada:
fonte
Encontrei outra solução:
Eu encontro uma maneira de detectar o link em um texto html que você encontra na Internet e o transforma em nsattributeString com:
Meu método permite detectar o hiperlink sem precisar especificá-los.
primeiro, você cria uma extensão do tapgesturerecognizer:
}
na exibição do controlador, você criou uma lista de URLs e intervalos para armazenar todos os links e o intervalo que o texto do atributo contém:
para encontrar o URL e o URLRange, você pode usar:
então você implementa a torneira da alça:
e aqui vamos nós!
Espero que esta solução ajude você como ela me ajude.
fonte
Para links totalmente personalizados, você precisará usar um UIWebView - é possível interceptar as chamadas, para que você possa acessar outra parte do aplicativo quando pressionar um link.
fonte
Aqui está uma categoria suspensa de Objective-C que permite links clicáveis em
UILabel.attributedText
cadeias existentes , explorando oNSLinkAttributeName
atributo existente .Isso seria um pouco mais limpo, feito por meio de uma subclasse UILabel (ou seja, nenhuma da bagunça objc_getAssociatedObject), mas se você é como eu, prefere evitar a criação de subclasses desnecessárias (de terceiros) apenas para adicionar alguma função extra às classes existentes do UIKit. Além disso, tem a beleza de adicionar links clicáveis a qualquer UILabel existente, por exemplo, existente
UITableViewCells
!Tentei torná-lo o menos invasivo possível, usando o
NSLinkAttributeName
atributo existente já disponível em NSAttributedString. Portanto, é simples como:Basicamente, ele funciona adicionando um
UIGestureRecognizer
ao seu UILabel. O trabalho duro é realizadogestureRecognizerShouldBegin:
, que re-layouts da string attributeText para descobrir qual caractere foi digitado. Se esse caractere fizer parte de um NSLinkAttributeName, o gestoRecognizer será acionado posteriormente, recuperará a URL correspondente (do valor NSLinkAttributeName) e abrirá o link pelo[UIApplication.sharedApplication openURL:url]
processo usual .Nota - ao fazer tudo isso
gestureRecognizerShouldBegin:
, se você não tocar em um link no rótulo, o evento será repassado. Assim, por exemplo, seu UITableViewCell capturará toques nos links, mas se comportará normalmente (selecione célula, desmarque, role, ...).Coloquei isso em um repositório GitHub aqui . Adaptado da publicação de SO de Kai Burghardt aqui .
fonte
Crie a classe com os seguintes arquivos. He. No arquivo .m, há a seguinte função
Dentro dessa função, verificaremos os intervalos de substrings para os quais precisamos executar ações. Use sua própria lógica para colocar seus intervalos.
E a seguir é o uso da subclasse
a seguir está o arquivo .h
a seguir está o arquivo .m
fonte
Eu recomendo fortemente o uso de uma biblioteca que detecte automaticamente os URLs no texto e os converta em links. Experimentar:
Ambos estão sob licença do MIT.
fonte
com base na resposta de Charles Gamble, foi isso que eu usei (removi algumas linhas que me confundiram e me deram um índice errado):
fonte
Solução drop-in como uma categoria ativada
UILabel
(isso pressupõe que vocêUILabel
use uma sequência atribuída com algunsNSLinkAttributeName
atributos):fonte
Aqui está uma implementação do Swift que é o mais mínima possível, que também inclui feedback por toque. Ressalvas:
"\u{a0}"
).link
chaves.
fonte
Este método genérico também funciona!
E você pode chamar o método com
fonte
UITapGestureRecognizer
vem? É uma saída? Uma propriedade que você configurou?Aqui é a minha resposta com base em de @Luca Davanzo resposta , substituir o
touchesBegan
evento em vez de um gesto de tocar:fonte
TAGS # Swift2.0
Inspiro - excelente - a resposta de @ NAlexN e decido escrever por mim mesmo um invólucro do UILabel.
Eu também tentei TTTAttributedLabel, mas não posso fazê-lo funcionar.
Espero que você possa apreciar esse código, todas as sugestões são bem-vindas!
fonte
0
causalocationOfTouchInTextContainer.x
negativa. Eu tento usar emlet indexOfCharacter = layoutManager.glyphIndex(for: locationOfTouch, in: textContainer)
vez disso, e funciona bem.fonte
Código @timbroder modificado para lidar com várias linhas corretamente para o swift4.2
Código UILabel
Código para reconhecer o Tap
fonte
Esta é uma implementação Xamarin.iOS c # baseada na resposta de Kedar .
Implementação MyClickableTextViewWithCustomUrlScheme com
ShouldInteractWithUrl
substituição:O código de objetivo-C convertido em c # se torna:
Certifique-se de definir Editable = false e Selectable = true para poder clicar no link.
Também ScrollEnabled = true permite que a visualização de texto dimensione sua altura corretamente.
fonte