Ярлык гиперссылки |
Clickable Label очень популярен в iOS, особенно на экране входа, регистрации. Вы можете легко увидеть такой текст:
Регистрируясь, я соглашаюсь условия обслуживания а также Политика конфиденциальности
Вот как я делаю эту этикетку.
Убедитесь, что текст, который нужно сделать кликабельным, полностью совпадает с полным текстом.
let termText = "By register, I agree to ... Terms of Service and Private Policy"
let term = "Terms of Service"
let policy = "Private Policy"
let termLabel = UILabel()
let formattedText = String.format(strings: [term, policy],
boldFont: UIFont.boldSystemFont(ofSize: 15),
boldColor: UIColor.blue,
inString: termText,
font: UIFont.systemFont(ofSize: 15),
color: UIColor.black)
termLabel.attributedText = formattedText
termLabel.numberOfLines = 0
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTermTapped))
termLabel.addGestureRecognizer(tap)
termLabel.isUserInteractionEnabled = true
termLabel.textAlignment = .center
String.format
является расширением из моей коллекции кода. Это полная функция.
extension String {
static func format(strings: [String],
boldFont: UIFont = UIFont.boldSystemFont(ofSize: 14),
boldColor: UIColor = UIColor.blue,
inString string: String,
font: UIFont = UIFont.systemFont(ofSize: 14),
color: UIColor = UIColor.black) -> NSAttributedString {
let attributedString =
NSMutableAttributedString(string: string,
attributes: [
NSAttributedStringKey.font: font,
NSAttributedStringKey.foregroundColor: color])
let boldFontAttribute = [NSAttributedStringKey.font: boldFont, NSAttributedStringKey.foregroundColor: boldColor]
for bold in strings {
attributedString.addAttributes(boldFontAttribute, range: (string as NSString).range(of: bold))
}
return attributedString
}
}
Я получаю местоположение крана в метке и проверяю, принадлежит ли это местоположение диапазону текста термина или политики.
@objc func handleTermTapped(gesture: UITapGestureRecognizer) {
let termString = termText as NSString
let termRange = termString.range(of: term)
let policyRange = termString.range(of: policy)
let tapLocation = gesture.location(in: termLabel)
let index = termLabel.indexOfAttributedTextCharacterAtPoint(point: tapLocation)
if checkRange(termRange, contain: index) == true {
handleViewTermOfUse()
return
}
if checkRange(policyRange, contain: index) {
handleViewPrivacy()
return
}
}
- Проверить, содержит ли диапазон индекс
func checkRange(_ range: NSRange, contain index: Int) -> Bool {
return index > range.location && index < range.location + range.length
}
- Получить индекс из точки в UILabel
extension UILabel {
func indexOfAttributedTextCharacterAtPoint(point: CGPoint) -> Int {
assert(self.attributedText != nil, "This method is developed for attributed string")
let textStorage = NSTextStorage(attributedString: self.attributedText!)
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: self.frame.size)
textContainer.lineFragmentPadding = 0
textContainer.maximumNumberOfLines = self.numberOfLines
textContainer.lineBreakMode = self.lineBreakMode
layoutManager.addTextContainer(textContainer)
let index = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
return index
}
}
И результат:
Вы можете скачать исходный код здесь
Вы можете создать собственный UILabel, чтобы его было проще использовать повторно. Я оставляю это для вас. Если у вас есть какие-либо проблемы с этим, дайте мне знать.
Наслаждайтесь кодированием.