我制作了一种按钮样式来在我的应用程序中创建圆形神经拟态按钮,如下所示:
struct NeumorphicCircleButtonStyle: ButtonStyle {
var startPoint: UnitPoint
var endPoint: UnitPoint
var padding: CGFloat?
var bgColor: Color?
var bgColorOffset: Color?
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(padding ?? 30)
.contentShape(Circle())
.background(
Group{
if configuration.isPressed {
Circle()
.fill(bgColor ?? Color.backgroundColor)
.overlay(
Circle()
.stroke(Color.black.opacity(0.7), lineWidth: 4)
.blur(radius: 4)
.offset(x: 2, y: 2)
.mask(Circle().fill(LinearGradient(colors: [Color.black, Color.clear], startPoint: startPoint, endPoint: endPoint)))
)
.overlay(
Circle()
.stroke(bgColorOffset ?? Color.backgroundColorOffset, lineWidth: 8)
.blur(radius: 4)
.offset(x: -2, y: -2)
.mask(Circle().fill(LinearGradient(colors: [Color.clear, Color.black], startPoint: startPoint, endPoint: endPoint)))
)
} else {
Circle()
.fill(bgColor ?? Color.backgroundColor)
.shadow(color: Color.black.opacity(0.25), radius: 10, x: 10, y: 10)
.shadow(color: bgColorOffset ?? Color.backgroundColorOffset.opacity(0.7), radius: 10, x: -5, y: -5)
}
}
)
}
// TODO: this will change the x y on the first set and need to make for other x y sets for direction, but can't find a good place for the logic, can't call it from in the makebody anywhere
func getXoffetInnerShadow() -> Int {
switch endPoint {
case .bottomTrailing:
return 2
case .bottomLeading:
return -2
case .topTrailing:
return 2
case .topLeading:
return -2
case .leading:
return -2
case .trailing:
return 2
default:
return 0
}
}
func getYoffsetInnerShadow() -> Int {
switch endPoint {
case .bottomTrailing:
return 2
case .bottomLeading:
return 2
case .bottom:
return 2
case .topTrailing:
return -2
case .topLeading:
return -2
case .top:
return -2
default:
return 0
}
}
func getXoffetInnerHighlight() -> Int {
switch endPoint {
case .bottomTrailing:
return -2
case .bottomLeading:
return 2
case .topTrailing:
return -2
case .topLeading:
return -2
case .leading:
return 2
case .trailing:
return -2
default:
return 0
}
}
func getYoffsetInnerHighlight() -> Int {
switch endPoint {
case .bottomTrailing:
return -2
case .bottomLeading:
return -2
case .bottom:
return -2
case .topTrailing:
return 2
case .topLeading:
return 2
case .top:
return 2
default:
return 0
}
}
func getXoffsetShadow() -> Int {
switch endPoint {
case .bottomTrailing:
return 10
case .bottomLeading:
return -10
case .topTrailing:
return 10
case .topLeading:
return -10
case .leading:
return -10
case .trailing:
return 10
default:
return 0
}
}
func getYoffsetShadow() -> Int {
switch endPoint {
case .bottomTrailing:
return 10
case .bottomLeading:
return 10
case .bottom:
return 10
case .topTrailing:
return -10
case .topLeading:
return -10
case .top:
return -10
default:
return 0
}
}
func getXoffsetHighlight() -> Int {
switch endPoint {
case .bottomTrailing:
return -10
case .bottomLeading:
return 10
case .topTrailing:
return -10
case .topLeading:
return 10
case .leading:
return 10
case .trailing:
return -10
default:
return 0
}
}
func getYoffsetHighlight() -> Int {
switch endPoint {
case .bottomTrailing:
return -10
case .bottomLeading:
return -10
case .bottom:
return -10
case .topTrailing:
return 10
case .topLeading:
return 10
case .top:
return 10
default:
return 0
}
}
}
// this is how I init my gradient if you want a working example
extension LinearGradient {
init(_ colors: Color..., startPoint: UnitPoint, endPoint: UnitPoint) {
self.init(gradient: Gradient(colors: colors), startPoint: startPoint, endPoint: endPoint)
}
}
我试图根据传递给样式的渐变端点更改我的两个阴影和高光的偏移量,以便内部和外部发光和阴影始终位于按钮的适当两侧。但是,尝试将 switch case 添加到偏移值或函数调用以返回适当的值会产生Closure containing control flow statement cannot be used with result builder 'CommandsBuilder'
编译时异常。
有没有什么方法可以根据给样式的 UnitPoint 设置阴影和高光的偏移值,或者我是否必须为每种可能性制作一个按钮样式(这似乎是一个不可行的期望)?
非常感谢任何和所有帮助或建议!