skip to Main Content

How can I create 2 initializers in a SwiftUI view (which is a struct)?

I am trying to make an initializer take takes a title and a color and one that only takes a title.

I have tried to create convenience initializers, but it seems that Swift will not allow this.

Are convenience initializers useful in SwiftUI Views?

2

Answers


  1. You can do it, like this way:

    Convenience initializer are accessible in reference types! Not in value types (such as Struct)!


    struct CustomView: View {
    
        let title: String
        let color: Color
    
        init(title: String, color: Color) {
            self.title = title
            self.color = color
        }
        
        init(title: String) {
            self.title = title
            self.color = Color.black
        }
    
        var body: some View {
            
            Text(title)
                .foregroundColor(color)
            
        }
        
    }
    

    use case:

    struct ContentView: View {
    
        var body: some View {
            
            CustomView(title: "Hello")
            
            CustomView(title: "Hello", color: Color.red)
            
        }
    }
    
    Login or Signup to reply.
  2. struct CustomView: View {
        var title: String
        var color: Color = .black
        
        var body: some View {
            Text(title)
                .foregroundColor(color)
        }
    }
    
    struct FooView: View {
        var body: some View {
            CustomView(title: "Title")
            CustomView(title: "Hello", color: .red)
        }
    }
    

    Swift synthesizes memberwise initializers by default. That means you get an initializer that accepts values for each of the struct’s properties for free. You don’t have to write one manually.
    If any properties have default values, the generated initializer will use those as default values for the arguments.

    If you want your own initializer and you want to keep the generated initializer, write your own one in an extension on the type.

    Update: As pointed out by swiftPunk, this doesn’t give you two init functions, so if you need to do that:

    struct CustomView: View {
        let title: String
        var color: Color = .black
        
        var body: some View {
            Text(title)
                .foregroundColor(color)
        }
    }
    
    extension CustomView {
        init(title: String) {
            self.title = title
        }
    }
    

    Now you actually have two actual functions you can use if you need that (maybe you want to compose them or something)

    let f1 = CustomView.init(title:)
    let f2 = CustomView.init(title:color:)
    

    You can make title let instead of var if you like, but view structs are always recomputed anyway.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search