I'm trying to make clickable phone numbers with UITextView. I manage to get them working with TextView created in the Storyboard and linking them over with @IBOutlet
like the ones mentioned in How to display clickable links in UITextView.
But I'm not able to click TextViews
that were dynamically generated and I won't have the option to simply check the Detection Links and Behavior Selectable since these TextView are created by code instead of in storyboard.
Below is one of my function to get phone numbers
private func createPhoneNumber(text: String) -> UITextView {
let label = UITextView()
label.isEditable = false
label.isSelectable = true
label.isScrollEnabled = false
label.isUserInteractionEnabled = true
label.dataDetectorTypes = UIDataDetectorTypes.phoneNumber
let padding = label.textContainer.lineFragmentPadding
label.textContainerInset = UIEdgeInsetsMake(0, -padding, 0, -padding)
label.text = text
return label
}
These are my other functions to dynamically generate the stackview that the label TextView and link TextView
will be inside of.
private func createStackView(subViews: [UIView], xpadding: CGFloat) -> UIStackView {
let stackView = UIStackView(arrangedSubviews: subViews)
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.alignment = .fill
stackView.spacing = xpadding
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}
private func createLabelValue(text: String) -> UILabel {
let label = UILabel()
label.font = UIFont(name: label.font.fontName, size: CGFloat(14))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.text = text
return label
}
private func createConstraints(item: Any, toItemXW: Any, toItemY: Any, YPadding: CGFloat) -> [NSLayoutConstraint] {
let DEFAULT_MULTIPLIER = CGFloat(1)
let DEFAULT_PADDING = CGFloat(8)
let xconstraint = NSLayoutConstraint(item: item, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal,
toItem: toItemXW, attribute: NSLayoutAttribute.leading, multiplier: DEFAULT_MULTIPLIER, constant: DEFAULT_PADDING)
let yconstraint = NSLayoutConstraint(item: item, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal,
toItem: toItemY, attribute: NSLayoutAttribute.bottom, multiplier: DEFAULT_MULTIPLIER, constant: YPadding)
let widthConstraint = NSLayoutConstraint(item: item, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal,
toItem: toItemXW, attribute: NSLayoutAttribute.width, multiplier: DEFAULT_MULTIPLIER, constant: 0)
return [xconstraint, yconstraint, widthConstraint]
}
I used that function to create a phone number text link then added into a dynamically generated horizontal stackview
which is added into a vertical stackview
as a list.
@IBOutlet weak var stackview: UIStackView!
var prevStackView = self.stackview
let phone_label = self.createLabelValue(text: "Phone")
let phone_num = self.createPhoneNumber(text: "800-199-1999")
// Faculty Phone
let phoneStackView = self.createStackView(subViews: [phone_label, phone], xpadding: CGFloat(8))
self.stackview.addSubview(phoneStackView)
let constraintsFacultyPhone = self.createConstraints(item: phoneStackView, toItemXW: self.scroll_view, toItemY: prevStackView ?? "", YPadding: CGFloat(2))
prevStackView = phoneStackView
self.scroll_view.addConstraints(constraintsFacultyPhone)