如何在我绘制文本的自定义视图中使链接、电话号码可点击(与 textview 中的行为相同)?
Posted
技术标签:
【中文标题】如何在我绘制文本的自定义视图中使链接、电话号码可点击(与 textview 中的行为相同)?【英文标题】:How to make link, phone number clickable (Same behaviour as in textview) in a custom view where i draw text? 【发布时间】:2017-11-13 08:48:00 【问题描述】:我创建了一个视图并在其上绘制文本,我希望如果任何文本包含链接(超链接)或电话号码,它将是可点击的(与文本视图中的行为相同)那么如何实现呢?强>
我在其中绘制文本的视图代码:-
class DrawRectCellView: UIView
var text: NSAttributedString?
override init(frame: CGRect)
super.init(frame: frame)
required init(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
// Only override drawRect: if you perform custom drawing.
override func draw(_ rect: CGRect)
UIColor.white.setFill()
UIGraphicsGetCurrentContext()?.fill(rect)
// Drawing code
if let attributedText = text
attributedText.draw(in: rect)
表格单元的代码:-
class DrawRectCell: UITableViewCell
var cellView: DrawRectCellView?
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Initialization code
cellView = DrawRectCellView(frame: self.frame)
if let cell = cellView
cell.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue)))
cell.contentMode = UIViewContentMode.redraw
self.contentView.addSubview(cellView!)
required init(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
func setTextString(_ text: NSAttributedString)
if let view = cellView
view.text = text
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
我正在设置文本,例如 = www.google.com 或任何电话号码,它仅显示为普通文本(在 textview 中不显示(使其可点击))
【问题讨论】:
【参考方案1】:首先你需要像这样检测你的文本是否包含url或数字。
let input = "This is a test with the URL https://www.hackingwithswift.com to be detected."
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let matches = detector.matches(in: input, options: [], range: NSRange(location: 0, length: input.utf16.count))
for match in matches
guard let range = Range(match.range, in: input) else continue
let url = input[range]
print(url)
如果您在设置为 textview 后检测到 url,则需要像这样在 UITextView 上添加UITapGestureRecognizer
。
let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap")
textview.addGestureRecognizer(tapGesture)
func handleTap(sender: UITapGestureRecognizer)
if sender.state == .began
//write your code here for url tap
【讨论】:
我没有使用 textview 我正在使用视图和绘图文本,同样的事情适用于视图吗? 是的,你也可以在 uiview 上应用同样的东西。 它会让链接和数字突出显示吗? 当我们在文本视图中选择或点击数字时,苹果提供的默认操作表会显示吗?【参考方案2】:您可以在 DrawRectCellView 上添加 UITapGestureRecognizer 并将 IndexPath 设置为标签。在 UITapGestureRecognizer 的 selector 方法中,您可以获取被点击的 contentView 包含文本的子视图信息。
【讨论】:
【参考方案3】:在 TextView 中突出显示某些文本:
假设您有 textView textView
,那么您可以使用此代码突出显示 URL、电话号码等:
textView.dataDetectorTypes = [] // doesn't work if textfield isEditable is set to true
textView.linkTextAttributes = [NSForegroundColorAttributeName: UIColor.blue] // the default is blue anyway
如果您只想包含一些特定的要检测的数据类型,请将它们添加到数组中,如下所示:
textView.dataDetectorTypes = [.link]
以下是类型列表:
https://developer.apple.com/documentation/uikit/uidatadetectortypes
使整个视图可点击:
您可以将UITapGestureRecognizer
添加到视图中(如果它不包含电话号码或超链接,则不添加),如下所示:
https://***.com/a/28675664/7270113
此答案可能未使用您正在使用的 Swift 版本。如果是这样,编译器会告诉你如何改变它,所以它会起作用。
如果你不喜欢使用选择器,我推荐使用库Closures
https://github.com/vhesener/Closures,特别是这个https://vhesener.github.io/Closures/Extensions/UITapGestureRecognizer.html
【讨论】:
这不是关于 tapGesture 如何使文本看起来像链接(电话号码和超链接)。例如,我们有一个字符串“hello this is an example www.google.com end of example”,如果我们把它放在文本视图中,它会使 www.google.com 突出显示和可点击,当我们点击它时,它将重定向到那个网站所以如何在自定义视图中实现这一点,我在视图上绘制文本。 我没有使用 textview 。我正在使用一个绘制文本的视图,所以下面的代码可以与视图一起使用吗? 如果您将UITextView
作为子视图添加到您的单元格内容视图,您将节省大量时间和头痛。您甚至可以使用UIStackView
来平衡您单元格内的所有内容。为什么要画文字?直接将NSAttributedString
添加到UITextView
并以这种方式配置字体和大小等内容肯定会更容易。如果可以的话,你应该使用 Xcode 和 Swift 已经自带的原生元素。
我正在使用这种方法,因为带有 NsAttributedString 的 UITextView 会降低滚动行为,并且我希望平滑滚动,所以使用这种方法。
那是相当难以实现的。首先,您需要定义一些检测逻辑来遍历您的字符串并转换范围内的字符,这些字符是 URL 等的一部分。这应该是简单的部分,@Shauket Sheikh 的答案显示了如何做到这一点。现在您需要在这些链接上覆盖手势识别器,因此它们只会覆盖文本。这是我能想到的唯一方法。您基本上也必须在正确的位置绘制它们。除非每个绘制的文本只有一个链接。然后你可以让整个视图可点击,但这可能不是一个好的用户体验。以上是关于如何在我绘制文本的自定义视图中使链接、电话号码可点击(与 textview 中的行为相同)?的主要内容,如果未能解决你的问题,请参考以下文章