I currently have a custom UITextView that properly changes the color of a link to the custom color I have set, however, when I click and hold the link, and the animation plays that makes the link bigger and creates a boarder around the link before previewing the website, the link changes briefly back to the system default color, and when letting go, it changes back to my custom color. Is there anyway to have the link always be my custom color, even when clicking and holding?
struct AutoDetectedClickableDataView: UIViewRepresentable {
let text: String
let dataDetectors: UIDataDetectorTypes
@Binding var height: CGFloat
private func dataDectectorValue(_ dataDectecor: UIDataDetectorTypes) -> UInt64 {
var checkingTypes: [NSTextCheckingResult.CheckingType] = []
if dataDetectors.contains(.phoneNumber) {
checkingTypes.append(.phoneNumber)
}
if dataDetectors.contains(.link) {
checkingTypes.append(.link)
}
if dataDetectors.contains(.address) {
checkingTypes.append(.address)
}
if dataDetectors.contains(.calendarEvent) {
checkingTypes.append(.date)
}
if checkingTypes.isEmpty {
return 0
}
let intCheckingTypes: UInt64 = checkingTypes.reduce(0) { result, checkingType in
UInt64(result) | UInt64(checkingType.rawValue)
}
return intCheckingTypes
}
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.dataDetectorTypes = dataDetectors
textView.isEditable = false
textView.isScrollEnabled = false
textView.backgroundColor = .clear
textView.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: UIFont.systemFont(ofSize: 16.0), compatibleWith: textView.traitCollection)
textView.textColor = UIColor.label
textView.adjustsFontForContentSizeCategory = true
textView.textContainer.lineBreakMode = .byWordWrapping
textView.textContainerInset = .zero
textView.textContainer.lineFragmentPadding = 0
textView.translatesAutoresizingMaskIntoConstraints = false
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
textView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
textView.linkTextAttributes = [.foregroundColor: JeromesColors.UILinkColor]
textView.tintColor = JeromesColors.UILinkColor
for gesture in textView.gestureRecognizers ?? [] {
if gesture is UITapGestureRecognizer {
gesture.view?.tintColor = JeromesColors.UILinkColor
}
}
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
let font = UIFontMetrics(forTextStyle: .body).scaledFont(for: UIFont.systemFont(ofSize: 16.0), compatibleWith: uiView.traitCollection)
let color = UIColor.label
let attributed = NSMutableAttributedString(string: text, attributes: [
.font: font,
.foregroundColor: color
])
let detectorValue = dataDectectorValue(dataDetectors)
var matchCount = 0
if !dataDetectors.isEmpty, detectorValue != 0 {
let detector = try? NSDataDetector(types: detectorValue)
detector?.enumerateMatches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count)) { match, _, _ in
guard let match = match else { return }
if match.resultType == .date, let date = match.date, date < Date() {
return
} else {
attributed.addAttributes([
.foregroundColor: JeromesColors.UILinkColor,
.underlineStyle: NSUnderlineStyle.single.rawValue,
], range: match.range)
matchCount += 1
}
}
}
uiView.attributedText = attributed
if matchCount == 0 {
uiView.isSelectable = false
} else if matchCount > 0 {
uiView.isSelectable = true
}
DispatchQueue.main.async {
uiView.layoutIfNeeded()
let fittingSize = CGSize(width: uiView.bounds.width, height: .greatestFiniteMagnitude)
let size = uiView.sizeThatFits(fittingSize)
height = size.height
}
}
}