web-dev-qa-db-fra.com

UILabel - chaîne sous forme de texte et de liens

J'ai un UILabel dont je reçois le texte d'un serveur. Une partie du texte doit être identifiée en tant que liens, et lorsque vous les touchez, des actions doivent être effectuées. par exemple.

NSString * str = @ "Mon numéro de téléphone est le 645-345-2345 et mon adresse est le xyz ";

Ceci est le texte complet pour UILabel. Je n'ai qu'un seul UILabel pour afficher ce texte (le texte est dynamique. Je viens de donner un exemple.). En cliquant sur ces liens, je dois effectuer des actions telles que la navigation vers un autre écran ou passer un appel.
Je sais que je peux afficher ce texte à l’aide de OHAttributedLabel . Et les liens peuvent être affichés comme suit:

[label1 addCustomLink:[NSURL URLWithString:@"http://www.foodreporter.net"] inRange:[txt rangeOfString:someString]];  

Mais je me demande comment puis-je faire en sorte que ces liens de texte effectuent des opérations telles que la navigation vers un autre écran ou la réalisation d'un appel.
Faites-moi savoir si d'autres explications sont nécessaires.

71
Nitish

Vous pouvez ajouter des actions personnalisées à l’un des UILabel remplacements disponibles qui prennent en charge les liens à l’aide d’un schéma d’URL fake que vous intercepterez plus tard:

TTTAttributedLabel *tttLabel = <# create the label here #>;
NSString *labelText = @"Lost? Learn more.";
tttLabel.text = labelText;
NSRange r = [labelText rangeOfString:@"Learn more"]; 
[tttLabel addLinkToURL:[NSURL URLWithString:@"action://show-help"] withRange:r];

Ensuite, dans votre TTTAttributedLabelDelegate:

- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url {
    if ([[url scheme] hasPrefix:@"action"]) {
        if ([[url Host] hasPrefix:@"show-help"]) {
            /* load help screen */
        } else if ([[url Host] hasPrefix:@"show-settings"]) {
            /* load settings screen */
        }
    } else {
        /* deal with http links here */
    }
}

TTTAttributedLabel est un fork de OHAttributedLabel.

Si vous souhaitez une approche plus complexe, jetez un œil à Nimbus Attributed Label . Il supporte les liens personnalisés prêts à l'emploi.

130
djromero

Vous pouvez utiliser UITextView avec la détection de numéros de téléphone et de liens, OUI, l'interaction utilisateur OUI désactivée est activée au lieu d'UILabel.

18
Ganesh

Mon projet a utilisé avec succès OHAttributedLabel pour cela. Vérifiez

-(BOOL)attributedLabel:(OHAttributedLabel*)attributedLabel shouldFollowLink:(NSTextCheckingResult*)linkInfo;

méthode dans OHAttributedLabelDelegate ( lien ). Cela vous permet de décider de ce qui se passe quand un lien est cliqué. Si vous regardez la source de l'exemple du projet OHAttributedLabel , il est utilisé pour afficher une alerte. Si vous avez retourné NO dans ce cas (pour éviter que l'action par défaut ne se produise également), vous pouvez simplement faire ce que vous voulez, comme la navigation, etc.

Notez cependant que cela nécessite que vous puissiez déterminer l'action correctement à partir du texte. Pour notre projet, nous avons utilisé une solution légèrement plus sophistiquée, dans laquelle le serveur nous a envoyé un texte avec des balises et une liste de commandes à exécuter pour chaque balise.

9
Martin Gjaldbaek

Il y a un projet appelé FancyLabel qui correspond à ce dont vous avez besoin. Il faudra peut-être un peu de personnalisation. De plus, je pense que Three2 a cette fonctionnalité, mais elle pourrait être exagérée si vous ne l'utilisez pas déjà.

Il existe également une solution beaucoup plus simple, si tous vos liens sont des téléphones\adresses\urls. Vous pouvez simplement utiliser un UITextView au lieu d'un UILabel. Il a la détection automatique des téléphones, adresses, etc. (cochez les cases dans IB)

Vous pouvez également avoir des actions personnalisées en réponse à des événements de clic sur ces liens en redéfinissant openURL, comme expliqué ici

Y a-t-il une raison spécifique pour laquelle vous devez utiliser un UILabel au lieu d'un UITextView? Notez que de nombreuses implémentations d'étiquettes attribuées héritent d'UIView ou n'implémentent pas toutes les fonctionnalités d'UILabel.

6
adamsiton

Je ne suis pas fan de l'obligation d'utiliser UITextView ou d'une bibliothèque tierce alors que tout ce dont j'ai besoin est une étiquette légère qui rend les liens (et qui me dit quand ils sont exploités!)

Voici ma tentative d’une sous-classe légère UILabel capable de détecter les taps de liaison. L'approche est différente des autres que j'ai vues dans la mesure où elle permet d'accéder au UILabel partagé de NSLayoutManager via un rappel de délégué ajouté à NSTextStorage via une extension de catégorie. La beauté réside dans le fait que UILabel effectue sa mise en page et son dessin natifs - d’autres remplacements UILabel augmentent ou remplacent souvent le comportement natif par un NSLayoutManager/NSTextContainer supplémentaire.

Probablement sûr, mais un peu fragile sur l'App Store - utilisez-le à vos risques et périls!

https://github.com/TomSwift/TSLabel

3
TomSwift

Vous pouvez utiliser le bouton personnalisé pour donner l’apparence d’un lien. Vous pouvez également ajouter un geste sur l’étiquette personnalisée si vous ne souhaitez pas utiliser le bouton.

UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTappedOnLink:)];
// if labelView is not set userInteractionEnabled, you must do so
[labelView setUserInteractionEnabled:YES];
[labelView addGestureRecognizer:gesture];
3
Ali3n