4

Context

Hi, I am currently working a lot with SwiftUI and encountered a problem while working with Modifiers. I have this basic setup:


Code

// This TitleView Protocol should be adapted by all SwiftUI Views containing a Title.
protocol TitleView: View {
    var title: String { get set }
}

// This is one of many Views containing a Title, therefore it conforms to the TitleView Protocol.
struct SomeTitleView: TitleView {
    var title: String = "Hello World";

    var body: some View {
        Text(title)
    }
}

// This Extension adds the setTitle Modifier to all Views conforming to TitleView.
extension View where View: TitleView {
    func setTitle(_ title: String) -> some View {
        self.modifier(CRStyleModifier(title: title))
    }
}

// This ViewModifier is supposed to manipulate the Title Property inside Views conforming to TitleView. 
// However, I am not sure how to accomplish it.
struct TextModifier: ViewModifier {
    let title: String
    
    @ViewBuilder func body<Content: TitleView>(content: Content) -> some View {
        content 
        // How can I update the Title Property of the Content?
        // Once I make the body Method generic, I get this error message -> Type 'CRStyleModifier' does not conform to protocol 'ViewModifier'
    }
}

Question

How can I achieve my goal of having a custom Modifier that can modify not just basic things like foregroundColor and font but also more specific ones like title on all Views conforming to a specific protocol? Thanks a lot for your help!

2
  • Why do you need a ViewModifier for that? Why don't you just do the view modification inside your setTitle extension on TitleView? Commented Mar 18, 2022 at 9:44
  • @DávidPásztor That is also an idea. However, how would you accomplish it there? Commented Mar 18, 2022 at 9:54

1 Answer 1

5

A custom modifier is possible but is not needed in this case as would introduced unneeded complexity, instead your extension can look like

extension View where Self: TitleView {
    func setTitle(_ title: String) -> some View {
        var newView = self
        newView.title = title
        return newView
    }
}

Tested with Xcode 13.3

Sign up to request clarification or add additional context in comments.

3 Comments

Is it also possible to add a default implementation of the title property to all Views conforming to TitleView?
Yes, as for any protocol extension TitleView { var title: String get { "" } set { } } }
It is better to return TitleView instead of some View because this would allow for more functions like this, e.g. func setSubtitle(_ sub: String)->Title View etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.