我的attributed string
设置为UILabel
multiple underlines
,colors
如下图所示
我知道如何为整个标签设置点按手势(启用user interaction
),下面的是我的代码,包括设置underline
和为font colors
设置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
。我想要的是当用户点击“条款和条件”时触发不同的功能,并且当用户点击“隐私政策”时触发另一个不同的功能。我怎样才能做到这一点。 注意:我想点击两个不同的功能,一个用于“条款和条件”点击,另一个用于“隐私政策”点击,并且不想只是 打开链接
答案 0 :(得分:1)
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)
}
}*
答案 1 :(得分:0)
我发现你需要你的条款和隐私链接是可点击的,ios提供的简单方法是AttributedString,使用以下代码:
let theString = "I have agree with the terms and conditions and privacy policy"
let someAttributedString = NSMutableAttributedString(string: theString)
someAttributedString.addAttribute(NSLinkAttributeName, value: "http://www.google.com", range: NSMakeRange(22, 20))
titleLabel.attributedText = someAttributedString
TTTAttributedLabel可能是您的最佳解决方案:https://github.com/TTTAttributedLabel/TTTAttributedLabel
TTTAttributedLabel有以下代理
- (void)attributedLabel:(__unused TTTAttributedLabel *)label
didSelectLinkWithURL:(NSURL *)url
{
//do whatever you want
}
此外,如果您需要点击手势的解决方案,您可以在手势点击上找到该点并进行计算以检查点击它的位置以通过gestureRecognizer.locationInView方法执行您的操作