the*_*ooL 5 xcode ios swift swiftui viewbuilder
我制作了一个按钮样式来在我的应用程序中创建圆形同形按钮,如下所示:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
我试图根据传递给样式的渐变端点来更改两个阴影和高光的偏移,以便内部和外部发光和阴影始终位于按钮的适当一侧。但是,尝试向偏移值添加 switch case 或函数调用以返回适当的值会引发Closure containing control flow statement cannot be used with result builder 'CommandsBuilder'编译时异常。
有没有什么方法可以根据给定方向样式的 UnitPoint 设置阴影和高光的偏移值,或者我是否必须为每种可能性创建一个按钮样式(这似乎是一个不可行的期望)?
非常感谢任何和所有的帮助或建议!
Xcode 未能产生真正的错误,这就是他所说的CommandsBuilder.
通常,当您遇到此类问题时,请尝试逐块注释代码以定位问题。
在这种情况下,如果您注释if .. { } else { }并保留if其中的两个部分(只是为了构建它),Xcode 将能够告诉实际问题
在这种情况下LinearGradient没有init(colors: ...,所以两行
.mask(Circle().fill(LinearGradient(colors: [Color.black, Color.clear], startPoint: startPoint, endPoint: endPoint)))
Run Code Online (Sandbox Code Playgroud)
应替换为:
.mask(Circle().fill(LinearGradient(gradient: Gradient(colors: [Color.black, Color.clear]), startPoint: startPoint, endPoint: endPoint)))
Run Code Online (Sandbox Code Playgroud)
如果您想使用下面定义的函数,例如修饰符getXoffetInnerShadow的参数.offset,您应该将返回类型替换为CGFloat,因为这是唯一.offset接受的类型。
| 归档时间: |
|
| 查看次数: |
7882 次 |
| 最近记录: |