Issue #956
macOS
import Foundation
import SwiftUI
import AppKit
struct AttributedTextView: NSViewRepresentable {
@Binding var attributedText: NSAttributedString
var isEditable: Bool = true
final class Coordinator: NSObject {
let parent: AttributedTextView
init(
parent: AttributedTextView
) {
self.parent = parent
super.init()
}
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeNSView(context: Context) -> NSScrollView {
let view = NSTextView.scrollableTextView()
if let textView = view.documentView as? NSTextView {
textView.font = NSFont.preferredFont(forTextStyle: .body)
textView.drawsBackground = false
textView.isEditable = isEditable
textView.delegate = context.coordinator
textView.textContainerInset = NSSize(width: 6, height: 6)
}
return view
}
func updateNSView(_ view: NSScrollView, context: Context) {
guard
let textView = view.documentView as? NSTextView
else { return }
DispatchQueue.main.async {
if textView.attributedString() != attributedText {
textView.textStorage?.setAttributedString(attributedText)
}
}
}
}
extension AttributedTextView.Coordinator: NSTextViewDelegate {
func textDidChange(_ notification: Notification) {
guard
let textView = notification.object as? NSTextView
else { return }
parent.attributedText = textView.attributedString()
}
}
iOS
import Foundation
import SFSafeSymbols
import SwiftUI
import UIKit
struct AttributedTextView: UIViewRepresentable {
@Binding var attributedText: NSAttributedString
var isEditable: Bool = true
final class Coordinator: NSObject {
let parent: AttributedTextView
init(
parent: AttributedTextView
) {
self.parent = parent
super.init()
}
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeUIView(context: Context) -> UITextView {
let view = UITextView()
view.attributedText = attributedText
view.autocorrectionType = .no
view.autocapitalizationType = .none
view.spellCheckingType = .no
view.delegate = context.coordinator
view.isEditable = isEditable
return view
}
func updateUIView(_ view: UITextView, context: Context) {
if view.attributedText != attributedText {
view.attributedText = attributedText
}
}
}
extension AttributedTextView.Coordinator: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
parent.attributedText = textView.attributedText
}
}