Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Reuse Extension for multiple types

I am attempting to reuse a piece of functionality in an extension across multiple types but I’m currently having a difficult time with the types. My code is as follows:

struct TitleStyle: ViewModifier {
    func body(content: Content) -> some View {
        content.font(.system(size: 34, weight: .bold))
    }
}

protocol TextStyle {
    associatedtype V: View

    func textStyle<Style: ViewModifier>(_ style: Style) -> V
}


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

extension Text: TextStyle {}
extension TextEditor: TextStyle {}

This would allow me to create a reusable component as follows:

func ExpandingTextEditor<Style: ViewModifier>(text: Binding<String>, style: Style) -> some View {
    ZStack {
        TextEditor(text: text)
            .textStyle(style)

        Text(text.wrappedValue)
            .textStyle(style)
            .opacity(0)
            .padding(.all, 8)
    }
}

Looking at similar questions to mine on Stack Overflow I’ve managed to get to this stage but I am getting the errors:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • "Text does not conform to protocol TextStyle"
  • "TextEditor does not conform to protocol TextStyle"

What am I missing?

>Solution :

You just need extension to View, like

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

func ExpandingTextEditor<Style: ViewModifier>(text: Binding<String>, style: Style) -> some View {
    ZStack {
        TextEditor(text: text)
            .textStyle(style)

        Text(text.wrappedValue)
            .textStyle(style)
            .opacity(0)
            .padding(.all, 8)
    }
}

or if you want to limit to only specific views:

protocol TextStyle {}

extension Text: TextStyle {}
extension TextEditor: TextStyle {}

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

Tested with Xcode 13.3 / iOS 15.4

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading