skip to Main Content

Let’s say I have my enum with spacings:

        /// 5
        case tiny = 5.0
    }

and I want to create init for VStack with spacing: Const.SpacingSUI, sth like this:

extension VStack {
    init(alignment: HorizontalAlignment = .center, spacing: Const.SpacingSUI? = nil, @ViewBuilder content: () -> Content) {
        self.init(alignment: alignment, spacing: spacing?.rawValue, content: content)
    }
}

and I’m getting error in compile time: Ambiguous use of ‘init(alignment:spacing:content:)’
Ok, I get it. If I use all the parameters, it will be fine; otherwise, there will be an error.
But is it possible to have additional init with my custom type in spacing parameter?

2

Answers


  1. Because VStack already have a init init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content), so when you try overload it with Const.SpacingSUI and default value nil and call VStack.init(content: { which implicit indicate spacing is nil, compiler can not know which function it should call. A solution could be remove default value from your custom init

    extension VStack {
        init(alignment: HorizontalAlignment = .center, spacing: Const.SpacingSUI, @ViewBuilder content: () -> Content) {
            self.init(alignment: alignment, spacing: spacing.rawValue, content: content)
        }
    }
    
    Login or Signup to reply.
  2. A completely different approach to this problem is to use an enum with static properties, that way you can still use the enum (without having to access rawValue) when creating your VStack and you don’t need to implement an extra init

    enum SpacingsUI {
        static let tiny: CGFloat = 5.0
        //
    }
    
    VStack(spacing: SpacingsUI.tiny) {
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search