0

I have a SwiftUI View with two similar init blocks. The only thing different between them is the type of an Optional property (has a default value). Because of the fact that it is optional, when I call the view without it, I get an Ambiguous use of 'init' error.

I want the first init to be the default initializer for the View.

Here's what it looks like:

struct NewView: View {

  var a: String
  var b: String
  var c: AnyShapeStyle
  var d: String

  init(a: String, 
       b: String,
       c: LinearGradient =  LinearGradient(gradient: Gradient(colors: [Color.green, Color.blue]), startPoint: .top, endPoint: .bottom),
       d: String = "Linear") {
    
    self.a = a
    self.b = a
    self.c = AnyShapeStyle(c)
    self.d = d
  }

  init(a: String, 
       b: String,
       c: AngularGradient =  AngularGradient(colors: [.green, .blue], center: .center),
       d: String = "Angular") {
    
    self.a = a
    self.b = a
    self.c = AnyShapeStyle(c)
    self.d = d
  }
  ...
}

Hence calling the view like this would give me the error:

NewView(a: "a", b: "b")
4
  • What would be the result of calling the unit with an AngularGradient for c for then the string “Linear” for d? Commented Jan 2, 2022 at 11:12
  • So when do you want the other initialiser to be called? Specifically, when do you want the default value AngularGradient(colors: [.green, .blue], center: .center) to be used? Commented Jan 2, 2022 at 11:26
  • @Fogmeister the string for d doesn't matter I was just showing an example with two required properties and two properties with default values Commented Jan 3, 2022 at 3:26
  • @Sweeper I want to be able to fill the view with either a linear gradient or an angular gradient. So by default I have set the fill to be a Linear gradient but the view can be filled with a custom linear or angular gradient. Commented Jan 3, 2022 at 3:28

1 Answer 1

2

You can differentiate the initializers using different argument label.


struct NewView: View {
  ...
  init(name a: String, 
       b: String,
       c: AngularGradient =  AngularGradient(colors: [.green, .blue], center: .center),
       d: String = "Angular") {
    
    ...
  }
  ...
}

Now whenever you call the following then the initializer with LinearGradient will be used.

NewView(a: "a", b: "b")

And to call the initializer with AngularGradient write the following:

NewView(name: "a", b: "b")

Whenever you overload method make sure to write self explanatory argument label which will help the caller to choose the right method/initializer.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.