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:
- "Text does not conform to protocol TextStyle"
- "TextEditor does not conform to protocol TextStyle"
What am I missing?
CodePudding user response:
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