如何在Swift 3中仅针对UILabel的特定范围设置轻击手势 [英] How to set up a tap gesture only for specific ranges of a UILabel in Swift 3

查看:87
本文介绍了如何在Swift 3中仅针对UILabel的特定范围设置轻击手势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将attributed string设置为UILabel,而multiple underlinescolors如下图所示

I have an attributed string set to UILabel with multiple underlines , colors like below image

我知道如何为整个标签设置轻敲手势(启用user interaction),下面是我的代码,这是我所做的工作,包括设置underline和设置用于multiple ranges.

and I know How to setup a tap gesture for whole label (with enabling user interaction) and below is my code for what I have done including setting up underline and setting up font colors for multiple ranges.

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var mylabel: UILabel!

    var theString = "I have agree with the terms and conditions and privacy policy"

    override func viewDidLoad() {
        super.viewDidLoad()

        mylabel.text = theString


        let tap = UITapGestureRecognizer(target: self, action: #selector(ViewController.printme))
        mylabel.addGestureRecognizer(tap)

        setUnderline(theText: theString)

        // Do any additional setup after loading the view, typically from a nib.
    }

    func printme() {
        print("print this")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func setUnderline(theText : String) {
        //set up underline
        let textRange1 = NSMakeRange(22, 19)
        let textRange2 = NSMakeRange(47, (theText.characters.count-47))
        let attributedText = NSMutableAttributedString(string : theText)
        attributedText.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: textRange1)
        attributedText.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: textRange2)


        //setup colors
        attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSRange(location: 22,length: 20))
        attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSRange(location: 47,length: (theText.characters.count-47)))

        mylabel.attributedText = attributedText

    }

  • tap手势适用于whole label.我想要的是,当用户点击条款和条件"时会触发其他功能,而当用户点击隐私权政策"时会触发另一个功能.我怎样才能做到这一点.
    • The tap gesture work for whole label. what I want is when user tap on "terms and conditions" fire a different function and and when user tap on "privacy policy" fire another different function. how can I do that.
    • 注意:我想触发两个不同的功能,一个用于条款和条件"轻按,另一个用于隐私权政策"轻按,但不希望 打开链接

      Note : I want to fire two different functions one for "terms and conditions" tap, and other for "privacy policy" tap, and do not want to just open links

      推荐答案

          import UIKit
      
          protocol SSGastureDelegate:NSObjectProtocol {
              func callBack()
          }
          class SSUnderLineLabel: UILabel {
              var tapGesture: UITapGestureRecognizer?
      
            //Make weak refernece for SSGastureDelegate
             weak var delegate:SSGastureDelegate?
      
              required init(coder aDecoder: NSCoder) {
                  super.init(coder: aDecoder)!
                  self.initialization()
              }
              override init(frame: CGRect) {
                  super.init(frame: frame)
                  self.initialization()
              }
      
              func initialization(){
                  let newsString: NSMutableAttributedString = NSMutableAttributedString(string: self.text!)
                  let textRange = NSString(string: self.text!)
                  let substringRange = textRange.range(of: "Terms and Conditions") // You can add here for own specific under line substring
                  newsString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: substringRange)
                 // self.attributedText = newsString.copy() as? NSAttributedString
                  self.attributedText = newsString
                  self.tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapResponse))
                  self.isUserInteractionEnabled =  true
                  self.addGestureRecognizer(tapGesture!)
      
              }
      
              func tapResponse(recognizer: UITapGestureRecognizer) {
      
                  let text = (self.text)!
                  let termsRange = (text as NSString).range(of: "Terms and Conditions")
                  if (tapGesture?.didTapAttributedTextInLabel(label: self, inRange: termsRange))! {
                      print("Tapped terms conditions")
                      self.delegate?.callBack()
                  }
                  else {
                      print("Tapped none ")
                  }
              }
      
          }
      
          //MARK:UITapGestureRecognizer Extension
          //MARK:
          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)
              }
      
          }*`enter code here`
      
      
      
      
      **How to use it:**
      Assign this class for your label and follow these steps:
      Demo for use class:
      
      ViewController.swift
      //===============
      
      class ViewController: UIViewController,SSGastureDelegate {
       @IBOutlet var underlineLbl: SSUnderLineLabel!
      
       override func viewDidLoad() {
            super.viewDidLoad()
           self.underlineLbl.delegate = self
       }
      //Implement Delegate Method
       func callBack()
          {
      //Open a specific vc for underline tap are`enter code here`a.
              let termsconditionsVC = storyboard?.instantiateViewController(withIdentifier: "TermsConditionsVC") as! TermsConditionsVC
              self.present(termsconditions, animated: true, completion: nil)
      
          }
      }*
      

      这篇关于如何在Swift 3中仅针对UILabel的特定范围设置轻击手势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆