[英]How to make NSAttributedString link clickable
我需要將數字顯示為來自字符串輸入(包含字母和數字)的可點擊鏈接,並且在點擊該數字時它應該打開一個 iOS 呼叫撥號器並撥打該號碼。
下面是我目前嘗試過的方法,使數字看起來像一個可點擊的數字,並且 rest 所有文本都作為普通默認文本,黑色低於 formattedText var 已定義,
var formattedText: NSAttributedString{
let message = "Hey you can dial up {88 22 333} number for further assistance"
let linkRange = (message as NSString).range(of: fetchNumber) //fetchNumber method returns the content residing inside flower braces..
guard linkRange.location != NSNotFound else {return nil}
let finalString = NSMutableAttributedString(string: message, attributes:[.font: UIFont.scaledFont(from: .baseText16), foregroundColor: .black])
finalString.addAttributes([.foregroundColor: .blue], range: linkRange)
return finalString
}
上面function中的output是:您好,您可以撥打88 22 333
號碼尋求進一步幫助
並使數字可點擊,我嘗試使用此屬性文本輸入到 UITextView 並啟用 dataDetectorType 屬性,但它對我不起作用:(有什么方法可以通過 UILabel 本身或任何類型的 UIKit 元素實現它,任何建議都是非常感謝,謝謝
我已經嘗試在啟用了 dataDetectorType 屬性的情況下使用此屬性文本輸入到 UITextView,但它對我不起作用:( 有什么方法可以使 UILabel 本身或任何類型的 UIKit 元素發生這種情況,提前非常感謝任何建議,謝謝
首先,您需要在全球范圍內申報手機號碼。
var mobileNo = "88 22 333"
為您的文本設置屬性字符串並創建可點擊的 label。
func setupLabel() {
let fullString = "Hey you can dial up " + mobileNo + " number for further assistance"
let strNSString: NSString = fullString as NSString
let rangeNumber = (strNSString).range(of: mobileNo)
let attribute = NSMutableAttributedString.init(string: fullString)
attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.lightGray , range: rangeNumber)
attribute.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 16), range: rangeNumber)
lblNumber.attributedText = attribute
//Tap Gesture
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(lblNumberTapped))
lblNumber.addGestureRecognizer(tapGesture)
lblNumber.isUserInteractionEnabled = true
}
之后聲明點擊手勢的方法。
//MARK: - TapGesture Click events
@objc func lblNumberTapped(_ gesture: UITapGestureRecognizer) {
self.view.endEditing(true)
let text = self.lblNumber.text ?? ""
let recoverMobileNumber = (text as NSString).range(of: mobileNo)
if gesture.didTapAttributedTextInLabel(label: lblNumber, inRange: recoverMobileNumber) {
if let callUrl = URL(string: "tel://\(mobileNo)"), UIApplication.shared.canOpenURL(callUrl) {
UIApplication.shared.open(callUrl)
}
}
}
您需要 UITapGestureRecognizer 擴展來檢測點擊事件。
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 textBoundingBox = layoutManager.boundingRect(forGlyphRange: targetRange, in: 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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.