UITextView с гиперссылкой Term and Privacy открывается в другом UIViewController - PullRequest
0 голосов
/ 20 января 2020

Я работаю с TextView и хотел создать две разные ссылки в тексте, где пользователь принимает условия и политику конфиденциальности .

Также мне нужно, чтобы каждая ссылка открывала другой UIViewController.

Может кто-нибудь помочь мне с примером, чтобы понять, как этого добиться?

Мне нужно понять, как создать две гиперссылки и как открыть их в двух разных ViewControllers

Спасибо всем за любую помощь Вы можете дать мне


Например ... Я хотел бы получить TextView, подобный этому

enter image description here

Ответы [ 3 ]

1 голос
/ 20 января 2020

Вы можете использовать следующий метод делегата UITextView и строку атрибутов. Протестировано на swift 5.1 :

 let attributedString = NSMutableAttributedString(string: "By continueing you agree terms and conditions and the privacy policy")

        attributedString.addAttribute(.link, value: "terms://termsofCondition", range: (attributedString.string as NSString).range(of: "terms and conditions"))

        attributedString.addAttribute(.link, value: "privacy://privacypolicy", range: (attributedString.string as NSString).range(of: "privacy policy"))

        textView.linkTextAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.blue]
        textView.attributedText = attributedString
        textView.delegate = self
        textView.isSelectable = true
        textView.isEditable = false
        textView.delaysContentTouches = false
        textView.isScrollEnabled = false

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {

        if URL.scheme == "terms" {
            //push view controller 1
            return false
        } else  if URL.scheme == "privacy"{
           // pushViewcontroller 2
             return false
        }
        return true
        // let the system open this URL
    }

UITextView вызывает эту функцию, если пользователь нажимает или долго нажимает ссылку URL. Реализация этого метода не является обязательной. По умолчанию UITextview открывает те приложения, которые отвечают за обработку типа URL, и передает им URL. Вы можете использовать этот метод для запуска альтернативного действия

0 голосов
/ 20 января 2020

Установите свойства textView следующим образом.

textView.attributedText = "By Continuing, you aggree to terms <a href='http://termsandservicelink'>Terms Of Services</a> and <a href='https://privacypolicylink'>Privacy Policy</a>".convertHtml()
textView.isEditable = false
textView.dataDetectorTypes = [.link]
textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue, NSAttributedString.Key.underlineColor: UIColor.clear]

Вы можете обрабатывать событие касания вашей ссылки в этом делегате.

  func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
       //Check your url whether it is privacy policy or terms and do accordigly
        return true
    }

Вот расширение String.

extension String{
    func convertHtml() -> NSAttributedString{
        guard let data = data(using: .utf8) else { return NSAttributedString() }
        do{
            return try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }catch{
            return NSAttributedString()
        }
    }
}
0 голосов
/ 20 января 2020

Этот результат достигается с помощью NSAttributedString, с помощью NSAttributedString, мы можем стилизовать текст,

myLabel.text = "By signing up you agree to our Terms & Conditions and Privacy Policy"
let text = (myLabel.text)!
let underlineAttriString = NSMutableAttributedString(string: text)
let range1 = (text as NSString).rangeOfString("Terms & Conditions")
underlineAttriString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: range1)
let range2 = (text as NSString).rangeOfString("Privacy Policy")
underlineAttriString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: range2)
myLabel.attributedText = underlineAttriString

Расширить UITapGestureRecognizer, чтобы обеспечить удобную функцию для определения, если определенный диапазон (NSRange) включается при UILabel.

extension UITapGestureRecognizer {
    func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
        // Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: CGSize.zero)
        let textStorage = NSTextStorage(attributedString: label.attributedText!)

        // Configure layoutManager and textStorage
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        // Configure textContainer
        textContainer.lineFragmentPadding = 0.0
        textContainer.lineBreakMode = label.lineBreakMode
        textContainer.maximumNumberOfLines = label.numberOfLines
        let labelSize = label.bounds.size
        textContainer.size = labelSize

        // Find the tapped character location and compare it to the specified range
        let locationOfTouchInLabel = self.locationInView(label)
        let textBoundingBox = layoutManager.usedRectForTextContainer(textContainer)
        let textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
            (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
        let locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
            locationOfTouchInLabel.y - textContainerOffset.y);
        let indexOfCharacter = layoutManager.characterIndexForPoint(locationOfTouchInTextContainer, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        return NSLocationInRange(indexOfCharacter, targetRange)
    }
}

UITapGestureRecognizer отправке действия на tapLabel: и обнаружении с использованием метода расширения didTapAttributedTextInLabel:inRange:.

@IBAction func tapLabel(gesture: UITapGestureRecognizer) {
    let text = (myLabel.text)!
    let termsRange = (text as NSString).rangeOfString("Terms & Conditions")
    let privacyRange = (text as NSString).rangeOfString("Privacy Policy")

    if gesture.didTapAttributedTextInLabel(myLabel, inRange: termsRange) {
        print("Tapped terms")
    } else if gesture.didTapAttributedTextInLabel(myLabel, inRange: privacyRange) 
    {
        print("Tapped privacy")
    } else {
        print("Tapped none")
    }
}
...