Home > Mobile >  How can I make a smart and dynamic initialization depending on first choice on init in Swift?
How can I make a smart and dynamic initialization depending on first choice on init in Swift?

Time:11-15

I want define a smart initialization method that it understands the chosen first parameter and adjust itself for it!

Here is my code:

struct Test {

    enum Kind { case vertical, horizontal }
    enum VerticalAlignment { case top, center, bottom }
    enum HorizontalAlignment { case leading, center, trailing }
    
    
    // if kind == horizontal then just VerticalAlignment:
    init(kind: Kind, verticalAlignment: VerticalAlignment) {
        
    }
    
    // if kind == vertical then just HorizontalAlignment:
    init(kind: Kind, horizontalAlignment: HorizontalAlignment) {
        
    }
    
}

As you can see in my codes, I have an initialization parameter called kind, here would be logic, if i chose .vertical then I want my second parameter automatically adjust itself to HorizontalAlignment type!

The issue with my code is that we can chose .horizontal and also get HorizontalAlignment type for second parameter!

I want limit my initialization and make it mistake-proof initialization, my goal is JUST this 2 initialization way:

. vertical → HorizontalAlignment

. horizontal → VerticalAlignment


How can I have both parameters available for initialization with those limitation?

Update: use case

struct CustomLineShape: Shape {
    
    let kind: Kind
    let verticalAlignment: VerticalAlignment
    let horizontalAlignment: HorizontalAlignment
    

    enum Kind { case vertical, horizontal }
    enum VerticalAlignment { case top, center, bottom }
    enum HorizontalAlignment { case leading, center, trailing }
    
    init(kind: CustomLineShape.Kind, verticalAlignment: CustomLineShape.VerticalAlignment) {
        self.kind = kind
        self.verticalAlignment = verticalAlignment
        self.horizontalAlignment = .center
    }
    
    
    init(kind: CustomLineShape.Kind, horizontalAlignment: CustomLineShape.HorizontalAlignment) {
        self.kind = kind
        self.horizontalAlignment = horizontalAlignment
        self.verticalAlignment = .center
    }

    private func verticalFunction(rect: CGRect) -> CGFloat {
        switch verticalAlignment {
        case .top: return rect.minY
        case .center: return rect.midY
        case .bottom: return rect.maxY
        }
    }

    private func horizontalFunction(rect: CGRect) -> CGFloat {
        switch horizontalAlignment {
        case .leading: return rect.minX
        case .center: return rect.midX
        case .trailing: return rect.maxX
        }
    }


    func path(in rect: CGRect) -> Path {

        switch kind {
        case .horizontal:
            
            return Path { path in

                path.move(to: CGPoint(x: rect.minX, y: verticalFunction(rect: rect)))
                path.addLine(to: CGPoint(x: rect.maxX, y: verticalFunction(rect: rect)))
                
            }
            
        case .vertical:
            
            return Path { path in

                path.move(to: CGPoint(x: horizontalFunction(rect: rect), y: rect.minY))
                path.addLine(to: CGPoint(x: horizontalFunction(rect: rect), y: rect.maxY))
                
            }
 
        }
  
    }
    
}


struct ContentView: View {
    
    var body: some View {
        
        VStack {
            
            CustomLineShape(kind: .vertical, horizontalAlignment: .center)
                .stroke(style: StrokeStyle(lineWidth: 5))
                .foregroundColor(Color.red)
                .padding()
                .background(Color.black.cornerRadius(5.0))
            
            CustomLineShape(kind: .horizontal, horizontalAlignment: .center)
                .stroke(style: StrokeStyle(lineWidth: 5))
                .foregroundColor(Color.red)
                .padding()
                .background(Color.black.cornerRadius(5.0))
            
        }
        .padding()
         
    }
    
}

enter image description here

CodePudding user response:

struct Test {
    
    enum VerticalAlignment { case top, center, bottom }
    enum HorizontalAlignment { case leading, center, trailing }

    enum Kind { case vertical(VerticalAlignment),
                     horizontal(HorizontalAlignment) }
    
    init(kind: Kind) {
        switch kind {
        case .horizontal(let horizontalAlignment):
            switch horizontalAlignment {
            case .center:
                ...
            }
        case .vertical(let verticalAlignment):
            ...
        }
    }
    
}
  • Related