ios Swift(UIKit)在UILabel内单击时推送到新的视图控制器(P/U)

qyyhg6bp  于 2023-03-05  发布在  iOS
关注(0)|答案(2)|浏览(121)

我的应用程序中有一个注册页面,我希望用户能够在按下UILabel内的文本时查看服务条款(TermsOfServiceViewController)和隐私政策(PrivacyPolicyViewController)。
我的声明如下:“选中此框即表示您同意我们的服务条款和隐私策略”。当用户按“服务条款”时,我希望他们看到TermsOfServiceViewController;当用户按“隐私策略”时,我希望他们看到PrivacyPolicyViewController。
现在我的代码是这样的:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let termsOfServiceViewController = NavigationTapGestureRecognizer(target: self, action: #selector(termsOfServiceVCTapped))
    termsOfServiceViewController.viewController = self
    
    let privacyPolicyViewController = NavigationTapGestureRecognizer(target: self, action: #selector(privacyPolicyVCTapped))
    privacyPolicyViewController.viewController = self
    
    let string = NSMutableAttributedString(string: "By checking this box, you agree to our ")
    let attributedTermsOfService = NSMutableAttributedString(string: "Terms of Service", attributes: [NSAttributedString.Key.link: termsOfServiceViewController, NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue, NSAttributedString.Key.underlineColor: UIColor.appColor(LPColor.LightestPurple)!, NSAttributedString.Key.foregroundColor: UIColor.appColor(LPColor.LightestPurple)!])
    let additionalString = NSMutableAttributedString(string: " and our ")
    let attributedPrivacyPolicy = NSMutableAttributedString(string: "Privacy Policy", attributes: [NSAttributedString.Key.link: privacyPolicyViewController, NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue, NSAttributedString.Key.underlineColor: UIColor.appColor(LPColor.LightestPurple)!, NSAttributedString.Key.foregroundColor: UIColor.appColor(LPColor.LightestPurple)!])
    
    string.append(attributedTermsOfService)
    string.append(additionalString)
    string.append(attributedPrivacyPolicy)
    
    agreementLabel.attributedText = string
    
    agreementLabel.addGestureRecognizer(termsOfServiceViewController)
    agreementLabel.addGestureRecognizer(privacyPolicyViewController)
    agreementLabel.isUserInteractionEnabled = true
}

@objc func termsOfServiceVCTapped() {
        let vc = TermsOfServiceViewController.storyboardInstance(storyboardName: "Login") as! TermsOfServiceViewController
        navigationController?.pushViewController(vc, animated: true)
    }

@objc func privacyPolicyVCTapped() {
        let vc = PrivacyPolicyViewController.storyboardInstance(storyboardName: "Login") as! PrivacyPolicyViewController
        navigationController?.pushViewController(vc, animated: true)
    }

现在,这段代码允许点击整个UILabel(我相信这是因为我将addGestureRecognizer添加到整个agreementLabel),并且它只会进入privacyPolicyViewController。有什么方法可以将它们彼此分开,并且只在用户点击实际文本而不是整个标签时才检测点击?
另外,我的NavigationTapGestureRecognizer看起来像这样:

class NavigationTapGestureRecognizer: UITapGestureRecognizer {
    var viewController: UIViewController?

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesEnded(touches, with: event!)

    }
}

如果有任何建议,我可以得到,这将是太棒了。提前感谢。

trnvg8h3

trnvg8h31#

let vc = self.UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController.storyboard.id") as! viewControllerFileName 

self.navigationController?.pushViewController(vc, animated: true)
bksxznpy

bksxznpy2#

所以经过一番研究,我想出了解决办法。请看下面:
创建UITapGestureRecognizer的扩展:

extension UITapGestureRecognizer {

func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
   guard let attributedText = label.attributedText else { return false }

   let mutableStr = NSMutableAttributedString.init(attributedString: attributedText)
   mutableStr.addAttributes([NSAttributedString.Key.font : label.font!], range: NSRange.init(location: 0, length: attributedText.length))
   
   // If the label have text alignment. Delete this code if label have a default (left) aligment. Possible to add the attribute in previous adding.
   let paragraphStyle = NSMutableParagraphStyle()
   paragraphStyle.alignment = .center
   mutableStr.addAttributes([NSAttributedString.Key.paragraphStyle : paragraphStyle], range: NSRange(location: 0, length: attributedText.length))

   // Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
   let layoutManager = NSLayoutManager()
   let textContainer = NSTextContainer(size: CGSize.zero)
   let textStorage = NSTextStorage(attributedString: mutableStr)
   
   // 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)
 }

}

然后将属性添加到字符串和UITapGestureRecognizer:

class CreatePasswordViewController: UIViewController {
    
    @IBOutlet weak var agreementLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        agreementLabel.text = text
        self.agreementLabel.textColor = UIColor.gray
        let underlineAttributedString = NSMutableAttributedString(string: text)
        let openSansBoldFont = UIFont(name: "OpenSans-Bold", size: 14)
        
    let range1 = (text as NSString).range(of: "Terms of Service")
        underlineAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range1)
        underlineAttributedString.addAttribute(NSAttributedString.Key.font, value: openSansBoldFont, range: range1)
        underlineAttributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.purple, range: range1)
        
    let range2 = (text as NSString).range(of: "Privacy Policy")
        underlineAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range2)
        underlineAttributedString.addAttribute(NSAttributedString.Key.font, value: openSansBoldFont, range: range2)
        underlineAttributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.purple, range: range2)
        
        agreementLabel.attributedText = underlineAttributedString
        agreementLabel.isUserInteractionEnabled = true
        agreementLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapLabel(gesture:))))
    
    @objc func tapLabel(gesture: UITapGestureRecognizer) {
        let termsRange = (text as NSString).range(of: "Terms of Service")
        let privacyRange = (text as NSString).range(of: "Privacy Policy")
        
        if gesture.didTapAttributedTextInLabel(label: agreementLabel, inRange: termsRange) {
            let vc = TermsOfServiceViewController.storyboardInstance(storyboardName: "Login") as! TermsOfServiceViewController
            navigationController?.pushViewController(vc, animated: true)
        } else if gesture.didTapAttributedTextInLabel(label: agreementLabel, inRange: privacyRange) {
            let vc = PrivacyPolicyViewController.storyboardInstance(storyboardName: "Login") as! PrivacyPolicyViewController
            navigationController?.pushViewController(vc, animated: true)
        }
      }
    }

引用此链接:Tap on a part of text of UILabel

相关问题