如何为SwiftUI中的文本(...)组件创建基于枚举的.textstyle(.title)修饰符?

发布于 2025-02-07 15:20:03 字数 1161 浏览 0 评论 0 原文

我想以类似的方式实现文本的修改器设置,因为它已经存在于按钮。

又名:

Button( ... )
   .buttonStyle(.plain) // <-- .plain and not PlainStyle()

问题 当然,我不能使用不相同的不透明。如果是 view ,我可以将其包装在 anyview 中,但是对于 view> viewModifier s,我需要另一个解决方案。

错误:函数声明不透明的返回类型,但其身体中的返回语句没有匹配的基础类型

,这可能是一个奖励想法,它是一个 .textstyle(.title)(.title)修改器,但在我的中眼睛,它可以减少我的代码以大量写作。

来源


struct TitleStyle: ViewModifier {
    func body(content: Content) -> some View {
      ...
    }
}

struct BodyStyle: ViewModifier {
    func body(content: Content) -> some View {
      ...
    }
}


enum TextStyle {
    
    case title
    case body

    // Error: Function declares an opaque return type, 
    // but the return statements in its body do not have matching underlying types
    var modifier: some ViewModifier {
        switch self
        {
        case .title: return TitleStyle()
        case .body: return BodyStyle()
        }
    }
}

I want to implement a modifier setting for Texts in a similar way as it already exists for Buttons.

Aka:

Button( ... )
   .buttonStyle(.plain) // <-- .plain and not PlainStyle()

Problem
Of course I cannot use an opaque which is not really the same. If it would be a View I could wrap it in an AnyView but for ViewModifiers I need another solution.

Error: Function declares an opaque return type,but the return statements in its body do not have matching underlying types

Maybe it is a bonus idea to have something like a .textStyle(.title) modifier but in my eyes, it could reduce my code to write enormously.

Source


struct TitleStyle: ViewModifier {
    func body(content: Content) -> some View {
      ...
    }
}

struct BodyStyle: ViewModifier {
    func body(content: Content) -> some View {
      ...
    }
}


enum TextStyle {
    
    case title
    case body

    // Error: Function declares an opaque return type, 
    // but the return statements in its body do not have matching underlying types
    var modifier: some ViewModifier {
        switch self
        {
        case .title: return TitleStyle()
        case .body: return BodyStyle()
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

远昼 2025-02-14 15:20:03

它的工作方式不同。由于所有这些都是围绕仿制药,因此我们需要限制已知具体类型的声明。

因此,具有 titlestyle BodyStyle 声明和具体,我们可以指定

extension ViewModifier where Self == TitleStyle {
    static var title: TitleStyle { TitleStyle() }
}

extension ViewModifier where Self == BodyStyle {
    static var body: BodyStyle { BodyStyle() }
}

并声明上述使用的扩展名,

extension View {
    func textStyle<Style: ViewModifier>(_ style: Style) -> some View {
        ModifiedContent(content: self, modifier: style)
    }
}

因此我们可以作为Demo

struct Demo_Previews: PreviewProvider {
    static var previews: some View {
        Text("Demo")
            .textStyle(.title)
    }
}

“

使用Xcode 13.4/ios 15.5

It works different way. As all this is around generics we need to restrict declarations for known concrete types.

So, having TitleStyle and BodyStyle declared and concrete, we can specify

extension ViewModifier where Self == TitleStyle {
    static var title: TitleStyle { TitleStyle() }
}

extension ViewModifier where Self == BodyStyle {
    static var body: BodyStyle { BodyStyle() }
}

and then declare extension to use above like

extension View {
    func textStyle<Style: ViewModifier>(_ style: Style) -> some View {
        ModifiedContent(content: self, modifier: style)
    }
}

so as a result we can do as demo

struct Demo_Previews: PreviewProvider {
    static var previews: some View {
        Text("Demo")
            .textStyle(.title)
    }
}

demo

Prepared with Xcode 13.4 / iOS 15.5

Test module in GitHub

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文