一种简单而常规的方法来为按钮设置凹凸效果,但在SwiftUI中并不简单。
我正在尝试在scale
修饰符中更改tapGesture
,但没有任何效果。我不知道如何制作动画链,可能是因为SwiftUI没有动画。所以我的天真做法是:
@State private var scaleValue = CGFloat(1)
...
Button(action: {
withAnimation {
self.scaleValue = 1.5
}
withAnimation {
self.scaleValue = 1.0
}
}) {
Image("button1")
.scaleEffect(self.scaleValue)
}
显然它不起作用,按钮图像立即获得上一个比例值。
我的第二个想法是在0.8
事件上将比例更改为hold
的值,然后在release
事件之后将比例更改为1.2
,并在几毫秒后再次将其更改为{ {1}}。我猜想这种算法应该会产生更好且更自然的凹凸效果。但是我在SwiftUI中找不到合适的1.0
结构来处理gesture
事件。
P.S。为了便于理解,我将描述hold-n-release
算法的步骤:
hold-n-release
1.0
0.8
1.2
秒0.1
UPD::我找到了使用动画1.0
修饰符的简单解决方案。但是我不确定这是正确和明确的。此外,它也不涵盖delay
问题:
hold-n-release
UPD 2 :
我在上面的解决方案中注意到,作为参数传递给@State private var scaleValue = CGFloat(1)
...
Button(action: {
withAnimation {
self.scaleValue = 1.5
}
//
// Using delay for second animation block
//
withAnimation(Animation.linear.delay(0.2)) {
self.scaleValue = 1.0
}
}) {
Image("button1")
.scaleEffect(self.scaleValue)
}
修饰符的值并不重要:delay
或0.2
将具有相同的效果。也许是个虫?
因此,我使用了1000
实例而不是Timer
动画修改器。现在它可以按预期工作:
delay
UPD 3 :
在我们等待苹果官方更新之前,一种用于实现两个事件...
Button(action: {
withAnimation {
self.scaleValue = 1.5
}
//
// Replace it
//
// withAnimation(Animation.linear.delay(0.2)) {
// self.scaleValue = 1.0
// }
//
// by Timer with 0.5 msec delay
//
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
withAnimation {
self.scaleValue = 1.0
}
}
}) {
...
和touchStart
的合适解决方案是基于@average Joe answer的:
touchEnd
答案 0 :(得分:6)
struct ScaleButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 2 : 1)
}
}
struct Test2View: View {
var body: some View {
Button(action: {}) {
Image("button1")
}.buttonStyle(ScaleButtonStyle())
}
}
答案 1 :(得分:1)
是的,它看起来像个错误,但经过试验,我发现您可以这样做
我已经在https://youtu.be/kw4EIOCp78g上发布了一个演示
struct TestView: View {
@State private var scaleValue = CGFloat(1)
var body: some View {
ZStack {
CustomButton(
touchBegan: {
withAnimation {
self.scaleValue = 2
}
},
touchEnd: {
withAnimation {
self.scaleValue = 1
}
}
){
Image("button1")
}.frame(width: 100, height: 100)
Image("button1").opacity(scaleValue > 1 ? 1 : 0).scaleEffect(self.scaleValue)
}
}
}
struct CustomButton<Content: View>: UIViewControllerRepresentable {
var content: Content
var touchBegan: () -> ()
var touchEnd: () -> ()
typealias UIViewControllerType = CustomButtonController<Content>
init(touchBegan: @escaping () -> (), touchEnd: @escaping () -> (), @ViewBuilder content: @escaping () -> Content) {
self.touchBegan = touchBegan
self.touchEnd = touchEnd
self.content = content()
}
func makeUIViewController(context: Context) -> UIViewControllerType {
CustomButtonController(rootView: self.content, touchBegan: touchBegan, touchEnd: touchEnd)
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
}
class CustomButtonController<Content: View>: UIHostingController<Content> {
var touchBegan: () -> ()
var touchEnd: () -> ()
init(rootView: Content, touchBegan: @escaping () -> (), touchEnd: @escaping () -> ()) {
self.touchBegan = touchBegan
self.touchEnd = touchEnd
super.init(rootView: rootView)
self.view.isMultipleTouchEnabled = true
}
@objc required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.touchBegan()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
self.touchEnd()
}
//touchesEnded only works if the user moves his finger beyond the bound of the image and releases
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
self.touchEnd()
}
}
还有另外一件奇怪的事情,如果我们将第二张图片缩放到第一张图片,那么如果没有.frame(width: 100, height: 100)
,它将不会显示。
答案 2 :(得分:1)
干净整洁的import pandas as pd
df1 = pd.DataFrame({'S':[1,0.613,0.613,0.387,0], 'V1': [0,0.387,0,0.613,1],'V2': [0,0,0.387,0,0]})
print(df1)
S V1 V2
0 1.000 0.000 0.000
1 0.613 0.387 0.000
2 0.613 0.000 0.387
3 0.387 0.613 0.000
4 0.000 1.000 0.000
解决方案:
swiftUI
但是,您还需要将此代码段添加到项目中:
@State private var scaleValue = CGFloat(1)
...
Image("button1")
.scaleEffect(self.scaleValue)
.onTouchGesture(
touchBegan: { withAnimation { self.scaleValue = 1.5 } },
touchEnd: { _ in withAnimation { self.scaleValue = 1.0 } }
)