带有条款和隐私超链接的 UITextView 在不同的 UIViewController 中打开
UITextView with Term and Privacy Hyperlink open in different UIViewController
我正在使用 TextView
,我想在用户接受 条款和条件和隐私政策。
我还需要每个 link 打开一个 不同的 UIViewController
.
任何人都可以通过示例帮助我了解如何实现这一目标吗?
我需要了解如何创建两个 Hyper links 以及如何在两个不同的 中打开它们 ViewControllers
谢谢大家给我的帮助
例如...我想要一个类似这样的TextView
这个结果是使用NSAttributedString
,使用NSAttributedString
,我们可以设置文本样式,
myLabel.text = "By signing up you agree to our Terms & Conditions and Privacy Policy"
let text = (myLabel.text)!
let underlineAttriString = NSMutableAttributedString(string: text)
let range1 = (text as NSString).rangeOfString("Terms & Conditions")
underlineAttriString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: range1)
let range2 = (text as NSString).rangeOfString("Privacy Policy")
underlineAttriString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: range2)
myLabel.attributedText = underlineAttriString
扩展 UITapGestureRecognizer
以提供一个方便的功能来检测是否在 UILabel
.
中点击了某个范围 (NSRange)
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.locationInView(label)
let textBoundingBox = layoutManager.usedRectForTextContainer(textContainer)
let textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
let locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
locationOfTouchInLabel.y - textContainerOffset.y);
let indexOfCharacter = layoutManager.characterIndexForPoint(locationOfTouchInTextContainer, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
UITapGestureRecognizer
将动作发送到 tapLabel:
,并使用扩展方法 didTapAttributedTextInLabel:inRange:
.
进行检测
@IBAction func tapLabel(gesture: UITapGestureRecognizer) {
let text = (myLabel.text)!
let termsRange = (text as NSString).rangeOfString("Terms & Conditions")
let privacyRange = (text as NSString).rangeOfString("Privacy Policy")
if gesture.didTapAttributedTextInLabel(myLabel, inRange: termsRange) {
print("Tapped terms")
} else if gesture.didTapAttributedTextInLabel(myLabel, inRange: privacyRange)
{
print("Tapped privacy")
} else {
print("Tapped none")
}
}
像这样设置您的 textView 属性。
textView.attributedText = "By Continuing, you aggree to terms <a href='http://termsandservicelink'>Terms Of Services</a> and <a href='https://privacypolicylink'>Privacy Policy</a>".convertHtml()
textView.isEditable = false
textView.dataDetectorTypes = [.link]
textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue, NSAttributedString.Key.underlineColor: UIColor.clear]
您可以在此委托中处理 link 上的点击事件。
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
//Check your url whether it is privacy policy or terms and do accordigly
return true
}
这是字符串扩展。
extension String{
func convertHtml() -> NSAttributedString{
guard let data = data(using: .utf8) else { return NSAttributedString() }
do{
return try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
}catch{
return NSAttributedString()
}
}
}
您可以使用以下 UITextView 委托方法和已在 swift 5.1 上测试的属性字符串:
let attributedString = NSMutableAttributedString(string: "By continueing you agree terms and conditions and the privacy policy")
attributedString.addAttribute(.link, value: "terms://termsofCondition", range: (attributedString.string as NSString).range(of: "terms and conditions"))
attributedString.addAttribute(.link, value: "privacy://privacypolicy", range: (attributedString.string as NSString).range(of: "privacy policy"))
textView.linkTextAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.blue]
textView.attributedText = attributedString
textView.delegate = self
textView.isSelectable = true
textView.isEditable = false
textView.delaysContentTouches = false
textView.isScrollEnabled = false
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
if URL.scheme == "terms" {
//push view controller 1
return false
} else if URL.scheme == "privacy"{
// pushViewcontroller 2
return false
}
return true
// let the system open this URL
}
如果用户点击或长按 URL link,UITextView 将调用此函数。此方法的实现是可选的。默认情况下,UITextview 打开那些负责处理 URL 类型的应用程序并将 URL 传递给它们。您可以使用此方法触发替代操作
我正在使用 TextView
,我想在用户接受 条款和条件和隐私政策。
我还需要每个 link 打开一个 不同的 UIViewController
.
任何人都可以通过示例帮助我了解如何实现这一目标吗?
我需要了解如何创建两个 Hyper links 以及如何在两个不同的 中打开它们 ViewControllers
谢谢大家给我的帮助
例如...我想要一个类似这样的TextView
这个结果是使用NSAttributedString
,使用NSAttributedString
,我们可以设置文本样式,
myLabel.text = "By signing up you agree to our Terms & Conditions and Privacy Policy"
let text = (myLabel.text)!
let underlineAttriString = NSMutableAttributedString(string: text)
let range1 = (text as NSString).rangeOfString("Terms & Conditions")
underlineAttriString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: range1)
let range2 = (text as NSString).rangeOfString("Privacy Policy")
underlineAttriString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: range2)
myLabel.attributedText = underlineAttriString
扩展 UITapGestureRecognizer
以提供一个方便的功能来检测是否在 UILabel
.
(NSRange)
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.locationInView(label)
let textBoundingBox = layoutManager.usedRectForTextContainer(textContainer)
let textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
let locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
locationOfTouchInLabel.y - textContainerOffset.y);
let indexOfCharacter = layoutManager.characterIndexForPoint(locationOfTouchInTextContainer, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
UITapGestureRecognizer
将动作发送到 tapLabel:
,并使用扩展方法 didTapAttributedTextInLabel:inRange:
.
@IBAction func tapLabel(gesture: UITapGestureRecognizer) {
let text = (myLabel.text)!
let termsRange = (text as NSString).rangeOfString("Terms & Conditions")
let privacyRange = (text as NSString).rangeOfString("Privacy Policy")
if gesture.didTapAttributedTextInLabel(myLabel, inRange: termsRange) {
print("Tapped terms")
} else if gesture.didTapAttributedTextInLabel(myLabel, inRange: privacyRange)
{
print("Tapped privacy")
} else {
print("Tapped none")
}
}
像这样设置您的 textView 属性。
textView.attributedText = "By Continuing, you aggree to terms <a href='http://termsandservicelink'>Terms Of Services</a> and <a href='https://privacypolicylink'>Privacy Policy</a>".convertHtml()
textView.isEditable = false
textView.dataDetectorTypes = [.link]
textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue, NSAttributedString.Key.underlineColor: UIColor.clear]
您可以在此委托中处理 link 上的点击事件。
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
//Check your url whether it is privacy policy or terms and do accordigly
return true
}
这是字符串扩展。
extension String{
func convertHtml() -> NSAttributedString{
guard let data = data(using: .utf8) else { return NSAttributedString() }
do{
return try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
}catch{
return NSAttributedString()
}
}
}
您可以使用以下 UITextView 委托方法和已在 swift 5.1 上测试的属性字符串:
let attributedString = NSMutableAttributedString(string: "By continueing you agree terms and conditions and the privacy policy")
attributedString.addAttribute(.link, value: "terms://termsofCondition", range: (attributedString.string as NSString).range(of: "terms and conditions"))
attributedString.addAttribute(.link, value: "privacy://privacypolicy", range: (attributedString.string as NSString).range(of: "privacy policy"))
textView.linkTextAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.blue]
textView.attributedText = attributedString
textView.delegate = self
textView.isSelectable = true
textView.isEditable = false
textView.delaysContentTouches = false
textView.isScrollEnabled = false
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
if URL.scheme == "terms" {
//push view controller 1
return false
} else if URL.scheme == "privacy"{
// pushViewcontroller 2
return false
}
return true
// let the system open this URL
}
如果用户点击或长按 URL link,UITextView 将调用此函数。此方法的实现是可选的。默认情况下,UITextview 打开那些负责处理 URL 类型的应用程序并将 URL 传递给它们。您可以使用此方法触发替代操作