Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit bf076de

Browse files
committed
Refactor to remove the preference, which is not needed
1 parent 8d66e40 commit bf076de

File tree

4 files changed

+32
-83
lines changed

4 files changed

+32
-83
lines changed

Sources/AttributedText/AttributedText.swift

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)
66
public struct AttributedText: View {
7-
@StateObject private var store = TextViewStore()
7+
@StateObject private var textViewStore = TextViewStore()
88

99
private let attributedText: NSAttributedString
1010

@@ -14,36 +14,24 @@
1414

1515
public var body: some View {
1616
GeometryReader { geometry in
17-
TextViewWrapper(attributedText: attributedText, store: store)
18-
.preference(key: ContainerSizePreference.self, value: geometry.maxSize)
19-
}
20-
.onPreferenceChange(ContainerSizePreference.self) { value in
21-
store.onContainerSizeChange(value)
17+
TextViewWrapper(
18+
attributedText: attributedText,
19+
maxLayoutWidth: geometry.maxWidth,
20+
textViewStore: textViewStore
21+
)
2222
}
2323
.frame(
24-
idealWidth: store.intrinsicContentSize?.width,
25-
idealHeight: store.intrinsicContentSize?.height
24+
idealWidth: textViewStore.intrinsicContentSize?.width,
25+
idealHeight: textViewStore.intrinsicContentSize?.height
2626
)
2727
.fixedSize(horizontal: false, vertical: true)
2828
}
2929
}
3030

3131
@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)
3232
private extension GeometryProxy {
33-
var maxSize: CGSize {
34-
CGSize(
35-
width: size.width - safeAreaInsets.leading - safeAreaInsets.trailing,
36-
height: size.height - safeAreaInsets.top - safeAreaInsets.bottom
37-
)
38-
}
39-
}
40-
41-
@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)
42-
private struct ContainerSizePreference: PreferenceKey {
43-
static var defaultValue: CGSize?
44-
45-
static func reduce(value: inout CGSize?, nextValue: () -> CGSize?) {
46-
value = nextValue()
33+
var maxWidth: CGFloat {
34+
size.width - safeAreaInsets.leading - safeAreaInsets.trailing
4735
}
4836
}
4937

Sources/AttributedText/TextViewStore.swift

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,8 @@
66
final class TextViewStore: ObservableObject {
77
@Published var intrinsicContentSize: CGSize?
88

9-
weak var view: TextViewWrapper.View?
10-
11-
func onContainerSizeChange(_ containerSize: CGSize?) {
12-
guard let containerSize = containerSize,
13-
let view = self.view else { return }
14-
15-
view.maxWidth = containerSize.width
16-
}
17-
18-
func didInvalidateIntrinsicContentSize() {
19-
guard let view = self.view else { return }
20-
21-
intrinsicContentSize = view.intrinsicContentSize
9+
func didUpdateTextView(_ textView: TextViewWrapper.View) {
10+
intrinsicContentSize = textView.intrinsicContentSize
2211
}
2312
}
2413

Sources/AttributedText/TextViewWrapper+NSTextView.swift

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
@available(macOS 11.0, *)
66
struct TextViewWrapper: NSViewRepresentable {
77
final class View: NSTextView {
8-
weak var store: TextViewStore?
9-
10-
var maxWidth: CGFloat {
8+
var maxLayoutWidth: CGFloat {
119
get { textContainer?.containerSize.width ?? 0 }
1210
set {
1311
guard textContainer?.containerSize.width != newValue else { return }
@@ -17,7 +15,7 @@
1715
}
1816

1917
override var intrinsicContentSize: NSSize {
20-
guard maxWidth > 0,
18+
guard maxLayoutWidth > 0,
2119
let textContainer = self.textContainer,
2220
let layoutManager = self.layoutManager
2321
else {
@@ -27,19 +25,6 @@
2725
layoutManager.ensureLayout(for: textContainer)
2826
return layoutManager.usedRect(for: textContainer).size
2927
}
30-
31-
override func invalidateIntrinsicContentSize() {
32-
super.invalidateIntrinsicContentSize()
33-
store?.didInvalidateIntrinsicContentSize()
34-
}
35-
36-
func setAttributedText(_ attributedText: NSAttributedString) {
37-
// Avoid notifiying the store while the text storage is processing edits
38-
let store = self.store
39-
self.store = nil
40-
textStorage?.setAttributedString(attributedText)
41-
self.store = store
42-
}
4328
}
4429

4530
final class Coordinator: NSObject, NSTextViewDelegate {
@@ -56,7 +41,8 @@
5641
}
5742

5843
let attributedText: NSAttributedString
59-
let store: TextViewStore
44+
let maxLayoutWidth: CGFloat
45+
let textViewStore: TextViewStore
6046

6147
func makeNSView(context: Context) -> View {
6248
let nsView = View(frame: .zero)
@@ -70,19 +56,19 @@
7056
nsView.textContainer?.widthTracksTextView = false
7157
nsView.delegate = context.coordinator
7258

73-
nsView.store = store
74-
store.view = nsView
75-
7659
return nsView
7760
}
7861

7962
func updateNSView(_ nsView: View, context: Context) {
80-
nsView.setAttributedText(attributedText)
63+
nsView.textStorage?.setAttributedString(attributedText)
64+
nsView.maxLayoutWidth = maxLayoutWidth
65+
8166
nsView.textContainer?.maximumNumberOfLines = context.environment.lineLimit ?? 0
8267
nsView.textContainer?.lineBreakMode = NSLineBreakMode(truncationMode: context.environment.truncationMode)
83-
nsView.invalidateIntrinsicContentSize()
8468

8569
context.coordinator.openURL = context.environment.openURL
70+
71+
textViewStore.didUpdateTextView(nsView)
8672
}
8773

8874
func makeCoordinator() -> Coordinator {

Sources/AttributedText/TextViewWrapper+UITextView.swift

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,22 @@
55
@available(iOS 14.0, tvOS 14.0, macCatalyst 14.0, *)
66
struct TextViewWrapper: UIViewRepresentable {
77
final class View: UITextView {
8-
weak var store: TextViewStore?
9-
10-
var maxWidth: CGFloat = 0 {
8+
var maxLayoutWidth: CGFloat = 0 {
119
didSet {
12-
guard maxWidth != oldValue else { return }
10+
guard maxLayoutWidth != oldValue else { return }
1311
invalidateIntrinsicContentSize()
1412
}
1513
}
1614

1715
override var intrinsicContentSize: CGSize {
18-
guard maxWidth > 0 else {
16+
guard maxLayoutWidth > 0 else {
1917
return super.intrinsicContentSize
2018
}
2119

2220
return sizeThatFits(
23-
CGSize(width: maxWidth, height: .greatestFiniteMagnitude)
21+
CGSize(width: maxLayoutWidth, height: .greatestFiniteMagnitude)
2422
)
2523
}
26-
27-
override func invalidateIntrinsicContentSize() {
28-
super.invalidateIntrinsicContentSize()
29-
store?.didInvalidateIntrinsicContentSize()
30-
}
31-
32-
func setAttributedText(_ attributedText: NSAttributedString) {
33-
// Avoid notifiying the store while the text storage is processing edits
34-
let store = self.store
35-
self.store = nil
36-
self.attributedText = attributedText
37-
self.store = store
38-
}
3924
}
4025

4126
final class Coordinator: NSObject, UITextViewDelegate {
@@ -48,7 +33,8 @@
4833
}
4934

5035
let attributedText: NSAttributedString
51-
let store: TextViewStore
36+
let maxLayoutWidth: CGFloat
37+
let textViewStore: TextViewStore
5238

5339
func makeUIView(context: Context) -> View {
5440
let uiView = View()
@@ -62,19 +48,19 @@
6248
uiView.textContainer.lineFragmentPadding = 0
6349
uiView.delegate = context.coordinator
6450

65-
uiView.store = store
66-
store.view = uiView
67-
6851
return uiView
6952
}
7053

7154
func updateUIView(_ uiView: View, context: Context) {
72-
uiView.setAttributedText(attributedText)
55+
uiView.attributedText = attributedText
56+
uiView.maxLayoutWidth = maxLayoutWidth
57+
7358
uiView.textContainer.maximumNumberOfLines = context.environment.lineLimit ?? 0
7459
uiView.textContainer.lineBreakMode = NSLineBreakMode(truncationMode: context.environment.truncationMode)
75-
uiView.invalidateIntrinsicContentSize()
7660

7761
context.coordinator.openURL = context.environment.openURL
62+
63+
textViewStore.didUpdateTextView(uiView)
7864
}
7965

8066
func makeCoordinator() -> Coordinator {

0 commit comments

Comments
 (0)