从 SwiftUI 视图返回文本

Posted

技术标签:

【中文标题】从 SwiftUI 视图返回文本【英文标题】:Return Text from a SwiftUI View 【发布时间】:2021-11-25 01:53:07 【问题描述】:

我有一个自定义的View,它基本上用一些附加功能包装了Text。例如。根据环境中的值对文本进行不同的格式化。

我想使用这个自定义视图来代替 Text,即我希望能够在其上使用像 .bold() 这样的修饰符。 是否可以从 View 结构返回 Text

【问题讨论】:

【参考方案1】:

这里有两种方法:

方式 1:您可以在 CustomView 上使用 .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())
        
    
    

结果:


方式 2:您可以在任何您想要的视图上使用.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())
    
    

结果:

【讨论】:

谢谢!您的第一个解决方案非常有帮助,并为我的用例提供了正确的方向。【参考方案2】:

您可以手动获取视图的body。虽然不推荐这样做,但可能的。然而,更好的解决方案可能是传入一个闭包来修改您的文本,请参阅第二个解决方案。两个答案都达到了同样的效果。

解决方案 #1(不推荐)

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
    

在这里,自定义文本被加粗。

解决方案 #2(推荐)

这个例子你只是传入了一个如何修改已经修改的自定义文本的闭包。这是我推荐的,而且看起来更干净。

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)
    

【讨论】:

嗨@George!谢谢您的回答!第一个解决方案似乎对我不起作用,因为getText() 中似乎没有环境可用。第二种解决方案似乎更好。当传入一个实际的String 作为参数时,我只需要让它工作,但我想我可以处理。我会试试然后回来! @Martin 我已经更新了我的示例,因此您可以传入一个字符串。此外,CustomText 应该仍然可以使用该环境。

以上是关于从 SwiftUI 视图返回文本的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中返回一个或两个不同文本视图的速记参数名称 $0 上添加条件

解析json数据后更新swiftui文本视图

如何从另一个视图swiftui中传递字段文本值

如何从内部的 SwiftUI 视图返回到 UIKit?

SwiftUI:如何计算文本视图的宽度?

SwiftUI 以编程方式从可表示返回到视图