Skip to content

Commit 289eb14

Browse files
committed
Update Text component
1 parent 758fa6f commit 289eb14

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

Sources/UIComponent/Components/View/Text.swift

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,21 @@ extension UIFont {
1111
/// An enumeration that represents the content of a `Text` component.
1212
/// It can either be a plain `String` or an `NSAttributedString` for more complex styling.
1313
public enum TextContent {
14-
case string(String)
14+
case string(String, UIFont)
1515
case attributedString(NSAttributedString)
16+
17+
func apply(to label: UILabel) {
18+
switch self {
19+
case .string(let string, let font):
20+
label.attributedText = nil
21+
label.font = font
22+
label.text = string
23+
case .attributedString(let string):
24+
label.font = nil
25+
label.text = nil
26+
label.attributedText = string
27+
}
28+
}
1629
}
1730

1831
/// A shared UILabel instance used for sizing text when `useSharedLabelForSizing` is true.
@@ -48,7 +61,7 @@ public struct Text: Component {
4861
numberOfLines: Int = 0,
4962
lineBreakMode: NSLineBreakMode = .byWordWrapping
5063
) {
51-
self.content = .string(text)
64+
self.content = .string(text, UIFont.systemFont(ofSize: UIFont.systemFontSize))
5265
self.numberOfLines = numberOfLines
5366
self.lineBreakMode = lineBreakMode
5467
self.isSwiftAttributedString = false
@@ -109,32 +122,32 @@ public struct Text: Component {
109122
/// - Parameter constraint: The constraints to use for laying out the text.
110123
/// - Returns: A `TextRenderNode` that represents the laid out text.
111124
public func layout(_ constraint: Constraint) -> TextRenderNode {
112-
let attributedString: NSAttributedString
113-
switch content {
114-
case .string(let string):
115-
attributedString = NSAttributedString(string: string, attributes: [.font: font, .foregroundColor: textColor])
116-
case .attributedString(let string):
117-
attributedString = string
118-
}
119125
if Self.useSharedLabelForSizing, Thread.isMainThread {
126+
// Fastest route, but not thread safe.
120127
layoutLabel.numberOfLines = numberOfLines
121128
layoutLabel.lineBreakMode = lineBreakMode
122-
switch content {
123-
case .string(let string):
124-
layoutLabel.font = font
125-
layoutLabel.text = string
126-
case .attributedString(let string):
127-
layoutLabel.font = nil
128-
layoutLabel.attributedText = string
129-
}
129+
content.apply(to: layoutLabel)
130130
let size = layoutLabel.sizeThatFits(constraint.maxSize)
131131
return TextRenderNode(
132-
attributedString: attributedString,
132+
content: content,
133133
numberOfLines: numberOfLines,
134134
lineBreakMode: lineBreakMode,
135135
size: size.bound(to: constraint)
136136
)
137137
}
138+
139+
let attributedString: NSAttributedString
140+
switch content {
141+
case .string(let string, let font):
142+
var attributes: [NSAttributedString.Key: Any] = [.font: self.font ?? font]
143+
if let color = textColor {
144+
attributes[.foregroundColor] = color
145+
}
146+
attributedString = NSAttributedString(string: string, attributes: attributes)
147+
case .attributedString(let string):
148+
attributedString = string
149+
}
150+
138151
if numberOfLines != 0 || isSwiftAttributedString {
139152
// Slower route
140153
//
@@ -154,7 +167,7 @@ public struct Text: Component {
154167
layoutManager.ensureLayout(for: textContainer)
155168
let rect = layoutManager.usedRect(for: textContainer)
156169
return TextRenderNode(
157-
attributedString: attributedString,
170+
content: content,
158171
numberOfLines: numberOfLines,
159172
lineBreakMode: lineBreakMode,
160173
size: rect.size.bound(to: constraint)
@@ -165,7 +178,7 @@ public struct Text: Component {
165178
options: [.usesLineFragmentOrigin],
166179
context: nil).size
167180
return TextRenderNode(
168-
attributedString: attributedString,
181+
content: content,
169182
numberOfLines: numberOfLines,
170183
lineBreakMode: lineBreakMode,
171184
size: size.bound(to: constraint)
@@ -177,7 +190,7 @@ public struct Text: Component {
177190
/// A `TextRenderNode` represents a renderable text node with styling and layout information.
178191
public struct TextRenderNode: RenderNode {
179192
/// The styled text to be rendered.
180-
public let attributedString: NSAttributedString
193+
public let content: TextContent
181194
/// The maximum number of lines to use for rendering. 0 means no limit.
182195
public let numberOfLines: Int
183196
/// The technique to use for wrapping and truncating the text.
@@ -187,12 +200,12 @@ public struct TextRenderNode: RenderNode {
187200

188201
/// Initializes a new `TextRenderNode` with the given parameters.
189202
/// - Parameters:
190-
/// - attributedString: The styled text to be rendered.
203+
/// - content: The styled text to be rendered.
191204
/// - numberOfLines: The maximum number of lines to use for rendering.
192205
/// - lineBreakMode: The technique to use for wrapping and truncating the text.
193206
/// - size: The calculated size of the rendered text.
194-
public init(attributedString: NSAttributedString, numberOfLines: Int, lineBreakMode: NSLineBreakMode, size: CGSize) {
195-
self.attributedString = attributedString
207+
public init(content: TextContent, numberOfLines: Int, lineBreakMode: NSLineBreakMode, size: CGSize) {
208+
self.content = content
196209
self.numberOfLines = numberOfLines
197210
self.lineBreakMode = lineBreakMode
198211
self.size = size
@@ -201,7 +214,7 @@ public struct TextRenderNode: RenderNode {
201214
/// Updates the provided `UILabel` with the render node's properties.
202215
/// - Parameter label: The `UILabel` to update with the text rendering information.
203216
public func updateView(_ label: UILabel) {
204-
label.attributedText = attributedString
217+
content.apply(to: label)
205218
label.numberOfLines = numberOfLines
206219
label.lineBreakMode = lineBreakMode
207220
}

Sources/UIComponent/Core/Model/Environment/EnvironmentKey/FontEnvironmentKey.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ import UIKit
99

1010
/// The key for accessing the default font from the environment.
1111
public struct FontEnvironmentKey: EnvironmentKey {
12-
public static var defaultValue: UIFont {
13-
UIFont.systemFont(ofSize: UIFont.systemFontSize)
12+
public static var defaultValue: UIFont? {
13+
nil
1414
}
1515
}
1616

1717
public extension EnvironmentValues {
1818
/// The font value in the environment.
19-
var font: UIFont {
19+
var font: UIFont? {
2020
get { self[FontEnvironmentKey.self] }
2121
set { self[FontEnvironmentKey.self] = newValue }
2222
}
@@ -26,7 +26,7 @@ public extension Component {
2626
/// Modifies the font environment value for the component.
2727
/// - Parameter font: The UIFont to be set in the environment.
2828
/// - Returns: An environment component with the new font value.
29-
func font(_ font: UIFont) -> EnvironmentComponent<UIFont, Self> {
29+
func font(_ font: UIFont?) -> EnvironmentComponent<UIFont?, Self> {
3030
environment(\.font, value: font)
3131
}
3232
}

Sources/UIComponent/Core/Model/Environment/EnvironmentKey/TextColorEnvironmentKey.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ import UIKit
99

1010
/// The key for accessing the default text color from the environment.
1111
public struct TextColorEnvironmentKey: EnvironmentKey {
12-
public static var defaultValue: UIColor {
13-
UIColor.label
12+
public static var defaultValue: UIColor? {
13+
nil
1414
}
1515
}
1616

1717
public extension EnvironmentValues {
1818
/// The text color value in the environment.
19-
var textColor: UIColor {
19+
var textColor: UIColor? {
2020
get { self[TextColorEnvironmentKey.self] }
2121
set { self[TextColorEnvironmentKey.self] = newValue }
2222
}
@@ -26,7 +26,7 @@ public extension Component {
2626
/// Modifies the text color environment value for the component.
2727
/// - Parameter color: The UIColor to be set in the environment.
2828
/// - Returns: An environment component with the new text color value.
29-
func textColor(_ color: UIColor) -> EnvironmentComponent<UIColor, Self> {
29+
func textColor(_ color: UIColor?) -> EnvironmentComponent<UIColor?, Self> {
3030
environment(\.textColor, value: color)
3131
}
32-
}
32+
}

0 commit comments

Comments
 (0)