如何检测文本中的所有链接并处理它们

时间:2017-07-04 20:37:47

标签: ios swift

大家好,这是我的第一个问题,如果我犯了一些错误,我很抱歉。

我正在创建一个显示网站内容的应用。要显示的数据是通过调用返回带有数据的json的服务器获得的。这是json的一个例子:

{
   "rubrique": {
      "id_rubrique": "10",
      "id_parent_rubrique": "10",
      "id_secteur_rubrique": "10",
      "titre_rubrique": "Rubrique title",
      "texte_rubrique": "- Le rubrique est un opérateur social de premier plan, présent dans toute rubrique et principalement dans le rubrique. Il intervient sur la totalité des métiers du logement social et offre ainsi, en accompagnement des politiques urbaines et sociales des collectivités, des solutions diversifiées leur permettant de répondre aux besoins et d'accompagner les familles dans leur parcours résidentiel.\nhttp://www.website.ft/rubrique/qui-sommes-nous\n\n- {{Entités}} : \n{{[Rubrique GIE->http://website.fr/spip.php?rubrique10]}}\n\n{{[Rubrique Habitat->http://website.fr/spip.php?rubrique11]}}\n\n{{[Rubrique Promotion->http://rubrique.fr/spip.php?rubrique10]}}\n\n{{[Rubrique de l’Île-de-France->http://website.fr/spip.php?rubrique12]}}\n\n{{Rubrique Maison}} : http://www.othersite.fr/qui-sommes-nous\n\n{{[Rubrique Sarepa\n->http://website.fr/spip.php?rubrique32]}}\n\n- [Agence locales de Rubrique->http://rubrique.fr/spip.php?rubrique155]\n\n- Organisation : \n{{Directeur rubrique }} : [Patrice Patrice->http://website.fr/spip.php?rubrique6002]\n\n{{Directeur général adjoint}} : [Farid Farid->http://website.fr/spip.php?rubrique20103]\n\n{{Secrétaire général}}: [Christian Christina->http://website.fr/spip.php?rubrique201014]\n\nDélégué général à la sécurité : [Roger Roger->http://website.fr/spip.php?rubrique2018]\n\n Directeur général d'Expansiel : [Frédéric Frédéric->http://website.fr/spip.php?rubrique2006]\n\n\nGrand Paris, Développement & relations institutionnelles : [Marie Marie->http://website.fr/spip.php?rubrique429]\n\nDirectrice de la communication : Ariane Ariane\n\nDirecteur des Ressources Humaines : Philippe Philippe\n\nDirection Contrôle de gestion et Comptabilité : Bernard Bernard\n\nDirection de la Maintenance & de l’Exploitation : [Marie-Line Marie->http://website.fr/spip.php?rubrique4561]\n\nDirection des Politiques Sociales, de la Qualité et des Attributions : \n[Caroline Caroline->http://website.fr/spip.php?rubrique1963] en remplacement de [Marie-Thérèse Marie->http://website.fr/spip.php?rubrique9221]\n\nDirection de l'Action Territoriale & du Renouvellement Urbain : [Fabienne Fabienne->http://website.fr/spip.php?rubrique3127]\nDirection des Projets urbains : [Delphine Delphine->http://website.fr/spip.php?rubrique17935] \n\nAdjoints Action Territoriale : Françoise Françoise, Philippe Philippe, Alain Alain\n\n\nDirecteur Technique & du Patrimoine : [Gilles Gilles->http://website.fr/spip.php?rubrique8260]\nAdjoint : Yvon Yvon\nResponsable marchés : Jocelyne Jocelyne\nChefs de programmes : Caroline Caroline, Xavier Xavier, Mireille David\n\nDirection des Systèmes d’Information : [Olivier Olivier->http://website.fr/spip.php?rubrique23050]\n\nDirection SG Expansiel Financements - Trésorerie - Moyens généraux : \n[François-François François-François->http://website.fr/spip.php?rubrique3649]\n\nhttps://www.othersite2.fr/sites/GV/0%2C%201%2C%202%2C%203%2C%204/file.pdf\nhttp://www.othersite2.fr/qui-sommes-nous/notre-organisation-et-organigramme\n",
      "contact_rubrique": "contact_rubrique",
      "fonction_rubrique": "fonction",
      "statut_rubrique": "publie",
      "maj_rubrique": "2017-06-23 09:14:21",
      "logo_rubrique": "http://website.fr/IMG/aaaaaa.png",
      "permission_documenter_rubrique": "false",
      "permission_instituer_rubrique": "true",
      "permission_voir_rubrique": "true",
      "permission_supprimer_rubrique": "false",
      "permission_modifier_rubrique": "true",
      "permission_iconifier_rubrique": "true",
      "permission_ajouter_article_rubrique": "true",
      "permission_ajouter_breve_rubrique": "false",
      "permission_ajouter_rubrique_rubrique": "true"
   }
}

texte_rubrique 标记的内容显示在UITextView中,当用户点击文本中的链接时,我需要拦截。当用户点击链接时,我不打开Web浏览器,但我必须导航到另一个视图。

现在我的问题是这样的:如何拦截链接上的点按?我写了一些代码,但不是我想要的完美。这就是我的尝试。

首先,我创建了一个UITextView并添加了一个点按重新整理器

let testoRubricaView = UITextView()
let tap = UITapGestureRecognizer(target: self, action: #selector(DettaglioSingoloElementoViewController.HandleTap(sender:)))
    testoRubricaView.addGestureRecognizer(tap) // add gesture recognizer to text view.

在这里,我尝试拦截文本中的所有链接,并尝试从文本中删除链接并重新点击链接附近的单词(类似于浏览器的href标记):

func getAttributedString() -> NSMutableAttributedString {
    let testo = rubricaCorrente.testoRubrica

    let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    let matches = detector.matches(in: testo, options: [], range: NSRange(location: 0, length: testo.utf16.count))

    //Create a variable of the text you wish to attribute.
    let textToAttribute = testo  // or "This is sample text"

    // Break your string in to an array, to loop through it.
    let textToAttributeArray = textToAttribute.components(separatedBy: "\n")

    // Define a variable as an NSMutableAttributedString() so you can append to it in your loop.
    let attributedText = NSMutableAttributedString()

    // Create a For - In loop that goes through each word your wish to attribute.
    for word in textToAttributeArray{
        // Create a pending attribution variable. Add a space for linking back together so that it doesn't looklikethis.

        if(word.contains("->") && word.contains("{{[")){

            let indexParolaInizio = word.range(of: "{{[")?.upperBound
            let indexParolaFine = word.range(of: "->")?.lowerBound
            let parolaRange = Range(uncheckedBounds: (indexParolaInizio!, indexParolaFine!))
            //var parola = word.substring(to: indexParolaFine!)
            var parola = word.substring(with: parolaRange)

            let attributePending = NSMutableAttributedString(string: parola + "\n")
            // Set an attribute on part of the string, with a length of the word.
            let myRange = NSRange(location: 0, length: parola.characters.count)
            // Create a custom attribute to get the value of the word tapped

            let indexLinkInizio = word.range(of: "->")?.upperBound
            let indexLinkFine = word.range(of: "]}}")?.lowerBound
            let linkRange = Range(uncheckedBounds: (indexLinkInizio!, indexLinkFine!))
            let link = word.substring(with: linkRange)

            let myCustomAttribute = [ "Tapped Word:": link]
            // Add the attribute to your pending attribute variable
            attributePending.addAttributes(myCustomAttribute, range: myRange)

            //append 'attributePending' to your attributedText variable.
            attributedText.append(attributePending)
        } else {
            let attributePending = NSMutableAttributedString(string: word + "\n")
            attributedText.append(attributePending)
        }
    }


    return attributedText
}

这是我的敲击手柄

func HandleTap(sender: UITapGestureRecognizer) {

    let myTextView = sender.view as! UITextView //sender is TextView
    let layoutManager = myTextView.layoutManager //Set layout manager

    // location of tap in myTextView coordinates

    var location = sender.location(in: myTextView) //locationInView(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) //characterIndexForPoint(location, inTextContainer: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

    // if index is valid then do something.
    if characterIndex < myTextView.textStorage.length {

        // print the character index
        print("Your character is at index: \(characterIndex)") //optional character index.

        // print the character at the index
        let myRange = NSRange(location: characterIndex, length: 1)
        let substring = (myTextView.attributedText.string as NSString).substring(with: myRange) //substringWithRange(myRange)
        print("character at index: \(substring)")

        // check if the tap location has a certain attribute
        let attributeName = "Tapped Word:" //make sure this matches the name in viewDidLoad()
        let attributeValue = myTextView.attributedText.attribute(attributeName, at: characterIndex, effectiveRange: nil) as? String //attribute(attributeName, atIndex: characterIndex, effectiveRange: nil) as? String
        if let value = attributeValue {
            print("You tapped on \(attributeName) and the value is: \(value)")
        }

    }
}

此代码无法正常运行。有些链接被检测到其他链接不是,但我不知道为什么。任何人都可以帮助我吗?

如果您需要任何其他信息,请向我提出,先谢谢。

的Alessandro

更新

在stackoverflow上进行了一些搜索后,我发现这个解决方案How do you make a UITextView detect link part in the text and still have userInteractionDisabled?我跟着答案,最后我可以拦截所有链接上的点击。大!!为了完美,我应该链接链接到关键字,以便链接不会出现在文本中,但只有关键字(如浏览器href)。

0 个答案:

没有答案