【发布时间】:2021-11-25 01:53:07
【问题描述】:
我有一个自定义的View,它基本上用一些附加功能包装了Text。例如。根据环境中的值对文本进行不同的格式化。
我想使用这个自定义视图来代替 Text,即我希望能够在其上使用像 .bold() 这样的修饰符。
是否可以从 View 结构返回 Text?
【问题讨论】:
标签: swiftui
我有一个自定义的View,它基本上用一些附加功能包装了Text。例如。根据环境中的值对文本进行不同的格式化。
我想使用这个自定义视图来代替 Text,即我希望能够在其上使用像 .bold() 这样的修饰符。
是否可以从 View 结构返回 Text?
【问题讨论】:
标签: swiftui
这里有两种方法:
.bold()!struct CustomTextView: View {
@Environment(\.font) var environmentFont: Font?
private let boldAllowed: Bool
let string: String
private init(boldAllowed: Bool, string: String) {
self.boldAllowed = boldAllowed
self.string = string
}
init(_ string: String) {
self.init(boldAllowed: false, string: string)
}
var body: some View {
Text(string)
.font(boldAllowed ? environmentFont?.bold() : environmentFont)
.foregroundColor(Color.red) // <--- ::: some custom work here! :::
}
func bold() -> CustomTextView {
return CustomTextView(boldAllowed: true, string: string)
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
CustomTextView("Hello, World!")
.bold()
CustomTextView("Hello, World!")
}
.font(Font.title.italic())
}
}
.bold()!我认为这是最好的方法,因为它的代码更少,并且在任何视图上都可用!
struct CustomBoldTextViewModifier: ViewModifier {
@Environment(\.font) var environmentFont: Font?
func body(content: Content) -> some View {
return content
.environment(\.font, environmentFont?.bold())
}
}
extension View {
func bold() -> some View {
return self.modifier(CustomBoldTextViewModifier())
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
}
.bold()
.font(Font.title.italic())
}
}
【讨论】:
您可以手动获取视图的body。虽然不推荐这样做,但是可能的。然而,更好的解决方案可能是传入一个闭包来修改您的文本,请参阅第二个解决方案。两个答案都达到了同样的效果。
struct ContentView: View {
var body: some View {
CustomText("Custom text")
.getText()
.bold()
.environment(\.font, .largeTitle)
}
}
struct CustomText: View {
private let content: String
init(_ content: String) {
self.content = content
}
var body: some View {
// Apply whatever modifiers from environment, etc.
Text(content)
}
func getText() -> Text {
body as! Text
}
}
在这里,自定义文本被加粗。
这个例子你只是传入了一个如何修改已经修改的自定义文本的闭包。这是我推荐的,而且看起来更干净。
struct ContentView: View {
var body: some View {
CustomText("Custom text") { text in
text
.bold()
.environment(\.font, .largeTitle)
}
}
}
struct CustomText<Content: View>: View {
private let content: String
private let transform: (Text) -> Content
init(_ content: String, transform: @escaping (Text) -> Content) {
self.content = content
self.transform = transform
}
var body: some View {
// Apply whatever modifiers from environment, etc.
let current = Text(content)
/* ... */
return transform(current)
}
}
【讨论】:
getText() 中似乎没有环境可用。第二种解决方案似乎更好。当传入一个实际的String 作为参数时,我只需要让它工作,但我想我可以处理。我会试试然后回来!
CustomText 应该仍然可以使用该环境。