按钮的延迟转换

我正在尝试转换 SwiftUI 项目中的按钮,这样当按钮被按下时,它会执行 .move(edge: .trailing),大约半秒后,按钮的不同图像将进入视图.

这是我目前所拥有的,正如预期的那样,图像同时发生变化。我很好奇这是否可以通过非对称转换来完成。尽量避免使用两个不同的按钮,它们的动画偏移会发生变化。

@State var delayedmove = false

@ViewBuilder
var moveMe: some View {
    HStack {
        Spacer()
        Button(action: {
            withAnimation {
                delayedmove.toggle()
            }
        }) {
            if delayedmove {
                selectImageButton
                    .animation(.linear.delay(delayedmove ? 0 : 1))
                    .transition(.move(edge: .trailing))
            } else {
                deleteImage
                    .animation(.linear.delay(!delayedmove ? 0 : 1))
                    .transition(.move(edge: .trailing))
                    
            }
            
        }
        .padding()
        
    }
}
fythlhan 回答:按钮的延迟转换

是的,您可以使用 asymmetric,无需重复代码。但是 SwiftUI 中的 Transition 需要两件事才能正常工作,首先是 Group,其次是 if & else,它现在是这样工作的,也许将来它会改变,但您可以看到代码:

enter image description here

struct ContentView: View {
    
    @State private var toggleButton = false
    
    var body: some View {
        
        HStack {
            
            Button("Toggle Button") { toggleButton.toggle() }
            
            Spacer()
            
            Button(action: { toggleButton.toggle() },label: {
                
                Group {
                    
                    if toggleButton {
                        
                        Image(systemName: "trash")
                        
                    }
                    else {
                        
                        Image(systemName: "plus")
                        
                    }
                    
                }
                .transition(AnyTransition.asymmetric(insertion: AnyTransition.move(edge: .trailing),removal: AnyTransition.move(edge: .trailing)))
                
            })
            
        }
        .padding()
        .animation(Animation.linear(duration: 0.5),value: toggleButton)
        
    }
}
,

你们很亲近。我只是将单个 if-else 拆分为 2 个 if,包裹在 ZStack 中。

按钮还使 secondaryDelay 等于 true 半秒,然后切换回 false

当视图离开层次结构时,过渡就开始了。我通过考虑 selectImageButton 的所有场景找到了实现此目的的方法:

  • 显示 - 显示:delayedMove = true,secondaryDelay = false
  • 开始隐藏 - 隐藏:delayedMove = false,secondaryDelay = true
  • 隐藏 - 隐藏:delayedMove = false,secondaryDelay = false
  • 开始显示 - 隐藏:delayedMove = true,secondaryDelay = true

从上面,我们只需要显示 delayedMove && !secondaryDelay 等于 true 时。其他 deleteImage 的类似方法。

代码:

struct ContentView: View {
    @State var delayedMove = false
    @State var secondaryDelay = false

    var body: some View {
        moveMe
    }

    @ViewBuilder
    var moveMe: some View {
        HStack {
            Spacer()
            Button(action: {
                withAnimation {
                    delayedMove.toggle()
                    secondaryDelay = true

                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                        secondaryDelay = false
                    }
                }
            }) {
                ZStack {
                    if delayedMove && !secondaryDelay {
                        selectImageButton
                            .animation(.linear)
                            .transition(.move(edge: .trailing))
                    }

                    if !delayedMove && !secondaryDelay {
                        deleteImage
                            .animation(.linear)
                            .transition(.move(edge: .trailing))
                    }
                }
            }
            .padding()
        }
    }
}

结果:

Result

,

如果您想要一个干净流畅的动画,比如第一个图像发出而另一个图像进入,您仍然可以使用相同的按钮并使用偏移量对标签进行动画处理。你可以试试这个视图

@State var delayedMove = false
var moveMe: some View {
        HStack {
            Spacer()
            Button(action: {
                withAnimation (.linear(duration: 0.5)){
                    delayedMove.toggle()
                }
            }) {
                ZStack{
                    Image(systemName: "trash")
                        .offset(x: delayedMove ? 0 : 200)
                    Image(systemName: "plus")
                        .offset(x: delayedMove ? 200 : 0)
                }
                .imageScale(.large)
            }
            .padding()
            
        }
    }
本文链接:https://www.f2er.com/3813.html

大家都在问