I’m making an attempt to embed a distant picture obtained from a URL right into a textual content utilizing TextKit2
I am utilizing NSTextAttachmentViewProvider
however I can not get it to work as anticipated.
There are two issues I can not perceive.
The conduct appears to be like like this
enter picture description right here
The code appears to be like like this
import SwiftUI
import SDWebImageSwiftUI
struct ContentView: View {
@State personal var textual content = "check"
var physique: some View {
MFMTextView(textual content: $textual content)
.body(maxWidth: .infinity)
}
}
let oyasu = URL(string: "https://media.misskeyusercontent.jp/misskey/f75cd6a7-61f9-4e72-b47f-9ce0b5aa8602.png")!
struct MFMTextView: UIViewRepresentable {
@Binding var textual content: String
typealias UIViewType = UITextView
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.isEditable = false
textView.delegate = context.coordinator
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
let attributedText = NSMutableAttributedString()
attributedText.append(NSAttributedString(string: textual content))
attributedText.append(NSAttributedString(attachment: ImageAttachment(url: oyasu)))
attributedText.append(NSAttributedString(string: textual content))
uiView.attributedText = attributedText
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var mum or dad: MFMTextView
init(_ mum or dad: MFMTextView) {
self.mum or dad = mum or dad
}
func textViewDidChange(_ textView: UITextView) {
}
}
}
remaining class ImageAttachment: NSTextAttachment {
let imageUrl: URL
init(url: URL) {
self.imageUrl = url
tremendous.init(information: nil, ofType: nil)
allowsTextAttachmentView = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been carried out")
}
override func viewProvider(
for parentView: UIView?,
location: NSTextLocation,
textContainer: NSTextContainer?
) -> NSTextAttachmentViewProvider? {
let viewProvider = ImageAttachmentViewProvider(
textAttachment: self,
parentView: parentView,
textLayoutManager: textContainer?.textLayoutManager,
location: location,
imageUrl: imageUrl
)
return viewProvider
}
}
remaining class ImageAttachmentViewProvider: NSTextAttachmentViewProvider {
let imageUrl: URL
init(
textAttachment: NSTextAttachment,
parentView: UIView?,
textLayoutManager: NSTextLayoutManager?,
location: NSTextLocation,
imageUrl: URL
) {
self.imageUrl = imageUrl
tremendous.init(
textAttachment: textAttachment,
parentView: parentView,
textLayoutManager: textLayoutManager,
location: location
)
tracksTextAttachmentViewBounds = true
}
override func loadView() {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
SDWebImageDownloader.shared.downloadImage(with: imageUrl) { [weak self] (picture, _, _, _) in
DispatchQueue.foremost.async { [weak self] in
imageView.picture = picture
self?.updateViewSize(for: picture)
}
}
self.view = imageView
self.view?.body.measurement.top = 25.0
}
personal func updateViewSize(for picture: UIImage?) {
guard let picture = picture else { return }
let aspectRatio = picture.measurement.width / picture.measurement.top
let top: CGFloat = 25
let width = top * aspectRatio
// Replace the view body with the brand new measurement
view?.body = CGRect(
x: 0.0,
y: 0.0,
width: width,
top: top
)
print(picture.measurement.width)
print(picture.measurement.top)
// Drive structure replace
view?.setNeedsLayout()
view?.layoutIfNeeded()
}
override func attachmentBounds(
for attributes: [NSAttributedString.Key : Any],
location: NSTextLocation,
textContainer: NSTextContainer?,
proposedLineFragment: CGRect,
place: CGPoint
) -> CGRect {
guard let imageView = view as? UIImageView, let picture = imageView.picture else {
return .zero
}
let top = 25.0
let aspectRatio = picture.measurement.width / picture.measurement.top
let width = top * aspectRatio
return CGRect(
x: 0.0,
y: 0.0,
width: width,
top: 100.0
)
}
}
Do you will have any good concepts?
Or know of some good pattern code?