Я сделал реализацию в this в моем ios app.but, когда базовый текст, заданный как, guard let text = self.lblTermsAndConditions.text else { return }
содержит двойные кавычки c didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool
возвращает false.
Например, когда текст, заданный lblTermsAndConditions , Нажав \ "Регистрация \", я принимаю Условия и политику конфиденциальности и privacyPolicyRange = Сроки и условия и политика конфиденциальности didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool
возвращает false.
мой код
@IBOutlet weak var privacyPolicyLabel: HuqLabel!{
didSet{
privacyPolicyLabel.text = "By clicking \"Signup\",I agree to the Terms and Conditions & Privacy Policy"
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.privacyPolicyLabel.isUserInteractionEnabled = true
let tapgesture = UITapGestureRecognizer(target: self, action: #selector(tappedOnLabel(_ :)))
tapgesture.numberOfTapsRequired = 1
tapgesture.numberOfTouchesRequired = 1
self.privacyPolicyLabel.addGestureRecognizer(tapgesture)
self.privacyPolicyLabel.isUserInteractionEnabled = true }
расширение в нижней части viewcontroller
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
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)
}
}
Я использую это так
guard let text = self.privacyPolicyLabel.text else { return }
let privacyPolicyRange = (text as NSString).range(of: "Terms and Conditions & Privacy Policy")
if gesture.didTapAttributedTextInLabel(label: self.privacyPolicyLabel, inRange: privacyPolicyRange) {
print("clicked on terms and conditions")
}else{
print("false")
}
Это печатает false. Как я могу это исправить?
Редактировать:
мой пользовательский ярлык
import UIKit
class HuqLabel: UILabel {
private var attributes = HuqStringAttributes.attributes(for: .bigTitle)
private var typograpyStyle: HuqTypographyStyle!
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configure()
}
private func configure() {
adjustsFontForContentSizeCategory = true
numberOfLines = 0
}
// Must be called after setting the attributed text
func setNumberOfLines(_ numOfLines: Int, breakMode: NSLineBreakMode = .byTruncatingTail) {
numberOfLines = numOfLines
lineBreakMode = breakMode
}
func setText(_ text: String) {
self.text = text
setLetterSpacing()
}
func set(_ text: String = "", typographyStyle: HuqTypographyStyle, alignment: NSTextAlignment = .left) {
typograpyStyle = typographyStyle
self.text = text
accessibilityLabel = text
self.attributes = HuqStringAttributes.attributes(for: typographyStyle, alignment: alignment)
setLetterSpacing()
}
func setAttributesForStrikeThrough(_ text: String, typographyStyle: HuqTypographyStyle, alignment: NSTextAlignment = .left) {
self.text = text
accessibilityLabel = text
self.attributes = HuqStringAttributes.attributes(for: typographyStyle, alignment: alignment)
let attributedString = NSMutableAttributedString(string: text, attributes: self.attributes)
attributedString.addAttribute(NSAttributedString.Key.kern, value: letterSpacingForTypographyStyle(for: typographyStyle), range: NSRange(location: 0, length: text.count))
attributedString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 1, range: NSMakeRange(0, attributedString.length))
attributedText = attributedString
}
func setLetterSpacing() {
let attributedString = NSMutableAttributedString(string: self.text ?? "", attributes: self.attributes)
attributedString.addAttribute(NSAttributedString.Key.kern, value: letterSpacingForTypographyStyle(for: typograpyStyle), range: NSRange(location: 0, length: self.text?.count ?? 0))
attributedText = attributedString
}
private func letterSpacingForTypographyStyle(for typographyStyle: HuqTypographyStyle) -> CGFloat {
switch typographyStyle {
case .bigTitle, .title, .bodyLight, .bodyWhite, .caption, .bodyBoldWhite, .bodyBoldBlue, .bodyBalck, .bodySmall, .titleBlue, .captionBlack, .bigTitleOrange, .captionMediumBlue:
return 0
}
}
func setText(_ text: String,
withBoldTextSections boldSections: [String], font: UIFont = FontFamily.Ubuntu.bold.font(size: 16),color:UIColor = ColorName.brownGrey.color) {
let attributes = HuqStringAttributes.attributes(for: .bodyLight, alignment: .center)
let attributedFullString = NSMutableAttributedString(string: text,
attributes: attributes)
boldSections.forEach { section in
let rangeOfSection = attributedFullString.mutableString.range(of: section)
attributedFullString.addAttributes([
NSAttributedString.Key.foregroundColor: color,
NSAttributedString.Key.font:font], range: rangeOfSection)
}
attributedText = attributedFullString
}
-
import Foundation
enum HuqTypographyStyle {
case bigTitle
case bigTitleOrange
case title
case titleBlue
case bodyLight
case bodyWhite
case bodyBalck
case caption
case captionBlack
case bodyBoldBlue
case bodyBoldWhite
case bodySmall
case captionMediumBlue
-
import Foundation
import UIKit
struct HuqFonts {
static func font(for typographyStyle: HuqTypographyStyle) -> UIFont {
switch typographyStyle {
case .bigTitle, .bigTitleOrange:
return ubuntuMedium(size: 30)
case .title, .titleBlue:
return ubuntuMedium(size: 18)
case .bodyLight, .bodyBalck:
return ubuntuRegular(size: 16)
case .bodyWhite:
return ubuntuRegular(size: 14)
case .caption, .captionBlack:
return ubuntuRegular(size: 12)
case .bodyBoldBlue, .bodyBoldWhite:
return ubuntuBold(size: 16)
case .bodySmall:
return ubuntuRegular(size: 10)
case .captionMediumBlue:
return ubuntuMedium(size: 12)
}
}
private static func ubuntuMedium(size: CGFloat) -> UIFont {
return FontFamily.Ubuntu.medium.font(size: size)
}
private static func ubuntuRegular(size: CGFloat) -> UIFont {
return FontFamily.Ubuntu.regular.font(size: size)
}
private static func ubuntuBold(size: CGFloat) -> UIFont {
return FontFamily.Ubuntu.bold.font(size: size)
}
}
import UIKit
struct HuqStringAttributes {
static func attributes(for typographyStyle: HuqTypographyStyle,
alignment: NSTextAlignment = .left) -> [NSAttributedString.Key: Any] {
var attributes: [NSAttributedString.Key: Any] = [:]
attributes[.font] = HuqFonts.font(for: typographyStyle).scaled
attributes[.foregroundColor] = colorsForTypographyStyles(for: typographyStyle).color
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = alignment
attributes[.paragraphStyle] = paragraphStyle
return attributes
}
private static func colorsForTypographyStyles(for typographyStyle: HuqTypographyStyle) -> ColorName {
switch typographyStyle {
case .bigTitle, .title, .bodyBalck, .captionBlack:
return ColorName.black
case .bodyLight ,.caption, .bodySmall:
return ColorName.brownGrey
case .bodyWhite, .bodyBoldWhite:
return ColorName.white
case .bodyBoldBlue, .titleBlue, .captionMediumBlue:
return ColorName.turquoiseBlue
case .bigTitleOrange:
return ColorName.bloodOrange
}
}
}