1
Fork 0
This repository has been archived on 2025-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
mobilefort/MobileFort/MobileFort (macOS)/AttributedText.swift

77 lines
2.3 KiB
Swift
Raw Normal View History

import SwiftUI
2020-11-18 08:18:26 -05:00
final class AttributedTextComponent: NSViewRepresentable {
let string: NSMutableAttributedString
init(_ string: NSMutableAttributedString) {
self.string = string
}
2020-11-18 08:18:26 -05:00
public func makeNSView(context: NSViewRepresentableContext<AttributedTextComponent>) -> NSTextField {
NSTextField()
}
2020-11-18 08:18:26 -05:00
func updateNSView(_ uiView: NSTextField, context: Context) {
uiView.backgroundColor = .clear
uiView.lineBreakMode = .byWordWrapping
uiView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
2020-11-18 08:18:26 -05:00
uiView.attributedStringValue = string
}
}
struct SizeKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
struct AttributedText: View {
let html: NSMutableAttributedString
let component: AttributedTextComponent
@State var height: CGFloat = 0.0
@State var lastSize: CGSize = .zero
init(_ html: NSMutableAttributedString) {
self.html = html.with(font: NSFont.systemFont(ofSize: NSFont.systemFontSize))
self.component = AttributedTextComponent(html)
}
func calculateHeight(size: CGSize) {
2020-11-18 08:18:26 -05:00
let label = NSTextField(frame: NSRect(x: 0, y: 0, width: size.width, height: .greatestFiniteMagnitude))
2020-11-18 08:18:26 -05:00
//label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
2020-11-18 08:18:26 -05:00
//label.attributedText = self.html
2020-11-18 08:18:26 -05:00
label.attributedStringValue = self.html
label.sizeToFit()
self.height = label.frame.height
self.lastSize = size
}
var body: some View {
ZStack {
GeometryReader { geometry in
Rectangle().fill(Color.clear).preference(key: SizeKey.self, value: geometry.size)
}.onPreferenceChange(SizeKey.self, perform: { size in
self.calculateHeight(size: size)
})
component
}
.frame(minWidth: 0.0, maxWidth: .infinity, minHeight: self.height, maxHeight: self.height)
.onAppear {
if self.lastSize != .zero {
self.calculateHeight(size: self.lastSize)
}
}
}
}