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()
}
}
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):
...
}
}
}