@@ -66,12 +66,13 @@ public struct RichView: View {
6666 } else if let error = error {
6767 ErrorView ( error: error)
6868 } else if let attributedString = attributedString {
69- SelectableTextView (
70- attributedString: attributedString,
71- fontSize: configuration. stylesheet. body. fontSize,
72- lineSpacing: configuration. stylesheet. body. lineSpacing,
73- onLinkTapped: onLinkTapped
74- )
69+ Text ( attributedString)
70+ . font ( . system( size: configuration. stylesheet. body. fontSize) )
71+ . lineSpacing ( configuration. stylesheet. body. lineSpacing)
72+ . environment ( \. openURL, OpenURLAction { url in
73+ onLinkTapped ? ( url)
74+ return . handled
75+ } )
7576 } else {
7677 Text ( " No content " )
7778 . foregroundColor ( . secondary)
@@ -246,70 +247,4 @@ public struct RenderMetadata {
246247
247248 /// Number of @mentions in the content
248249 public let mentionCount : Int
249- }
250-
251- // MARK: - Selectable Text View
252-
253- /// A UIViewRepresentable wrapper for UITextView that supports text selection
254- @available ( iOS 18 . 0 , * )
255- struct SelectableTextView : UIViewRepresentable {
256- let attributedString : AttributedString
257- let fontSize : CGFloat
258- let lineSpacing : CGFloat
259- let onLinkTapped : ( ( URL ) -> Void ) ?
260-
261- func makeUIView( context: Context ) -> UITextView {
262- let textView = UITextView ( )
263- textView. isEditable = false
264- textView. isSelectable = true
265- textView. isScrollEnabled = false
266- textView. backgroundColor = . clear
267- textView. textContainerInset = . zero
268- textView. textContainer. lineFragmentPadding = 0
269- textView. delegate = context. coordinator
270- textView. dataDetectorTypes = [ ]
271- textView. linkTextAttributes = [
272- . foregroundColor: UIColor . systemBlue,
273- . underlineStyle: NSUnderlineStyle . single. rawValue
274- ]
275- return textView
276- }
277-
278- func updateUIView( _ textView: UITextView , context: Context ) {
279- // Convert AttributedString to NSAttributedString
280- var nsAttributedString = NSAttributedString ( attributedString)
281-
282- // Apply line spacing
283- let paragraphStyle = NSMutableParagraphStyle ( )
284- paragraphStyle. lineSpacing = lineSpacing
285-
286- let mutableAttributedString = NSMutableAttributedString ( attributedString: nsAttributedString)
287- mutableAttributedString. addAttribute (
288- . paragraphStyle,
289- value: paragraphStyle,
290- range: NSRange ( location: 0 , length: mutableAttributedString. length)
291- )
292-
293- textView. attributedText = mutableAttributedString
294- }
295-
296- func makeCoordinator( ) -> Coordinator {
297- Coordinator ( onLinkTapped: onLinkTapped)
298- }
299-
300- class Coordinator : NSObject , UITextViewDelegate {
301- let onLinkTapped : ( ( URL ) -> Void ) ?
302-
303- init ( onLinkTapped: ( ( URL ) -> Void ) ? ) {
304- self . onLinkTapped = onLinkTapped
305- }
306-
307- func textView( _ textView: UITextView , shouldInteractWith URL: URL , in characterRange: NSRange , interaction: UITextItemInteraction ) -> Bool {
308- if interaction == . invokeDefaultAction {
309- onLinkTapped ? ( URL)
310- return false
311- }
312- return true
313- }
314- }
315250}
0 commit comments