Нажав какой-нибудь приписанный текст в метке Swift / Xcode - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь сделать какой-нибудь атрибутивный текст кликабельным в ярлыке.Я добавил к своему виду метку и наложил на нее автоматический макет.Затем я добавил tapGestureRecognizer к метке и подключил к ней @IBAction (у меня также есть выходы для метки и жеста).

@IBOutlet weak var label: UILabel!
@IBOutlet var gesture: UITapGestureRecognizer!
@IBAction func tapLabel(_ sender: UITapGestureRecognizer) {

    let text = label.text!
    let termsRange = (text as NSString).range(of: "Terms & Conditions")
    let privacyRange = (text as NSString).range(of: "Privacy Policy")

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

Затем я добавил расширение для распознавателя жестов.

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.location(in: label)
        let textBoundingBox = layoutManager.usedRect(for: textContainer)

        let textContainerOffset = CGPoint(x: (labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)

        let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y)

        let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        return NSLocationInRange(indexOfCharacter, targetRange)
    }
}

И функция (вызывается в ViewDidLoad)

func setupterm(){
    label.text = "By signing up you agree to our \nTerms & Conditions and Privacy Policy"
    let text = (label.text)!
    let underlineAttriString = NSMutableAttributedString(string: text)
    let range1 = (text as NSString).range(of: "Terms & Conditions")
    underlineAttriString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range1)
    let range2 = (text as NSString).range(of: "Privacy Policy")
    underlineAttriString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range2)

    label.attributedText = underlineAttriString
}

Когда я запускаю приложение на симуляторе, первый из двух терминов работает правильно (если я нажимаю «Условия иУсловия "он печатает, если я нажимаю где-то еще, он печатает" нет "), но проблема заключается во втором.На самом деле, если я нажимаю на текст «Конфиденциальность», он печатает «Конфиденциальность», но даже если я нажимаю под ним: Просто чтобы быть более ясным: если я нажимаю под текстом «Конфиденциальность», он не печатает «нет», нодействует как будто я нажимаю на "приватность"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...