J'essaie d'afficher une chaîne attribuée dans une vue UITextview avec des liens cliquables. J'ai créé un projet de test simple pour voir où je vais mal et je ne peux toujours pas le comprendre. J'ai essayé d'activer l'interaction utilisateur et de définir la méthode déléguée shouldInteractWithURLs, mais cela ne fonctionne toujours pas. Voici mon code (pour un contrôleur de vue qui ne contient qu'une vue de texte)
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let string = "Google"
let linkString = NSMutableAttributedString(string: string)
linkString.addAttribute(NSLinkAttributeName, value: NSURL(string: "https://www.google.com")!, range: NSMakeRange(0, string.characters.count))
linkString.addAttribute(NSFontAttributeName, value: UIFont(name: "HelveticaNeue", size: 25.0)!, range: NSMakeRange(0, string.characters.count))
textView.attributedText = linkString
textView.delegate = self
textView.selectable = true
textView.userInteractionEnabled = true
}
Et voici les méthodes déléguées que j'ai implémentées:
func textViewShouldBeginEditing(textView: UITextView) -> Bool {
return false
}
func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
return true
}
Cela ne fonctionne toujours pas. J'ai cherché sur ce sujet et rien n'a encore aidé. Merci beaucoup d'avance.
Pour Swift3.0
override func viewDidLoad() {
super.viewDidLoad()
let linkAttributes = [
NSLinkAttributeName: NSURL(string: "http://stalwartitsolution.co.in/luminutri_flow/terms-condition")!
] as [String : Any]
let attributedString = NSMutableAttributedString(string: "Please tick box to confirm you agree to our Terms & Conditions, Privacy Policy, Disclaimer. ")
attributedString.setAttributes(linkAttributes, range: NSMakeRange(44, 18))
attributedString.addAttribute(NSUnderlineStyleAttributeName, value: NSNumber(value: 1), range: NSMakeRange(44, 18))
textview.delegate = self
textview.attributedText = attributedString
textview.linkTextAttributes = [NSForegroundColorAttributeName: UIColor.red]
textview.textColor = UIColor.white
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
return true
}
Swift 3 iOS 10: Voici UITextView étendu cliquable qui détecte automatiquement les sites Web à l'intérieur de la vue de texte tant que le lien commence par www. par exemple: www.exmaple. com s'il existe n'importe où dans le texte sera cliquable. Voici la classe:
import Foundation
import UIKit
public class ClickableTextView:UITextView{
var tap:UITapGestureRecognizer!
override public init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
print("init")
setup()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup(){
// Add tap gesture recognizer to Text View
tap = UITapGestureRecognizer(target: self, action: #selector(self.myMethodToHandleTap(sender:)))
// tap.delegate = self
self.addGestureRecognizer(tap)
}
func myMethodToHandleTap(sender: UITapGestureRecognizer){
let myTextView = sender.view as! UITextView
let layoutManager = myTextView.layoutManager
// location of tap in myTextView coordinates and taking the inset into account
var location = sender.location(in: myTextView)
location.x -= myTextView.textContainerInset.left;
location.y -= myTextView.textContainerInset.top;
// character index at tap location
let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
// if index is valid then do something.
if characterIndex < myTextView.textStorage.length {
let orgString = myTextView.attributedText.string
//Find the WWW
var didFind = false
var count:Int = characterIndex
while(count > 2 && didFind == false){
let myRange = NSRange(location: count-1, length: 2)
let substring = (orgString as NSString).substring(with: myRange)
// print(substring,count)
if substring == " w" || (substring == "w." && count == 3){
didFind = true
// print("Did find",count)
var count2 = count
while(count2 < orgString.characters.count){
let myRange = NSRange(location: count2 - 1, length: 2)
let substring = (orgString as NSString).substring(with: myRange)
// print("Did 2",count2,substring)
count2 += 1
//If it was at the end of textView
if count2 == orgString.characters.count {
let length = orgString.characters.count - count
let myRange = NSRange(location: count, length: length)
let substring = (orgString as NSString).substring(with: myRange)
openLink(link: substring)
print("It's a Link",substring)
return
}
//If it's in the middle
if substring.hasSuffix(" "){
let length = count2 - count
let myRange = NSRange(location: count, length: length)
let substring = (orgString as NSString).substring(with: myRange)
openLink(link: substring)
print("It's a Link",substring)
return
}
}
return
}
if substring.hasPrefix(" "){
print("Not a link")
return
}
count -= 1
}
}
}
func openLink(link:String){
if let checkURL = URL(string: "http://\(link.replacingOccurrences(of: " ", with: ""))") {
if UIApplication.shared.canOpenURL(checkURL) {
UIApplication.shared.open(checkURL, options: [:], completionHandler: nil)
print("url successfully opened")
}
} else {
print("invalid url")
}
}
public override func didMoveToWindow() {
if self.window == nil{
self.removeGestureRecognizer(tap)
print("ClickableTextView View removed from")
}
}
}