SwiftUI 如何临时为视图颜色的前景颜色设置动画?

Posted

技术标签:

【中文标题】SwiftUI 如何临时为视图颜色的前景颜色设置动画?【英文标题】:SwiftUI how do I temporarily animate a view color's foregroundColor? 【发布时间】:2021-07-20 00:19:39 【问题描述】:

当按下视图时,我通过模型button.isSelected 知道。如何为视图的前景色设置动画,类似于 ios 计算器按钮按下动画?

类似:

白色 -> 灰色 -> 白色

struct ButtonView: View 
    let button: ViewModel.Button

    
    var body: some View 
        let shape = Rectangle()
        ZStack 
            shape.fill().foregroundColor(button.isSelected ? Color.gray : Color.white)
                .animation(Animation.linear(duration: 0.01))
            .border(Color.black, width: 0.33)
            Text(button.content)
            .font(Font.system(size:32))
            
        
    

【问题讨论】:

【参考方案1】:

我认为有很多方法可以做到这一点。 其中,我会写一个使用DispatchQueue.main.asyncAfter()的例子

struct ContentView: View 
    @State private var isSelected: Bool = false
    
    var body: some View 
        VStack 
            Button 
                isSelected = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2 ) 
                    // To change the time, change 0.2 seconds above
                    isSelected = false
                
             label: 
                Text("Button")
                    .foregroundColor(isSelected ? Color.red : Color.blue)
            
        
    

【讨论】:

【参考方案2】:

虽然DispatchQueue.main.asyncAfter() 将作为Taeeun answered 工作,但请注意计算器应用程序如何不使用设置的延迟。相反,当手指按下时它会改变颜色,然后在松开时恢复。

所以,您可能想要ButtonStyle 之类的东西。

struct ContentView: View 
    var body: some View 
        ButtonView()
    


struct CalculatorButtonStyle: ButtonStyle 
    func makeBody(configuration: Configuration) -> some View 
        configuration.label
            .padding() /// no need to use `shape` + `ZStack`, normal padding is ok
            .background(configuration.isPressed ? Color.gray : Color.white) /// use `isPressed` to determine if button is currently pressed or not
            .animation(Animation.linear(duration: 0.01))
            .cornerRadius(10)
    


struct ButtonView: View 
    var body: some View 
        ZStack 
            Color.black /// for testing purposes (see the button better)
            
            Button  label: 
                Text("Button")
                    .font(.system(size: 32))
            
            .buttonStyle(CalculatorButtonStyle()) /// apply the style
        
    

结果:

【讨论】:

感谢您,我能够清理我的项目的按钮代码! 必须是 Button 吗?我正在使用一种非常具体的风格 - 我使用 Rectangle 的原因 @JZ。如果您不想使用ButtonDispatchQueue.main.asyncAfter() 可能就是这样。但是对于Button来说,aheze的方式会比DispatchQueue.main.asyncAfter() 谢谢! @JZ。您仍然可以在 Button 中使用 Rectangle - 只需将 Text("Button") 替换为您想要的任何内容。

以上是关于SwiftUI 如何临时为视图颜色的前景颜色设置动画?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:为特定视图设置状态栏颜色

使用 SwiftUI 为启用/禁用按钮设置颜色的最智能方法

SwiftUI:如何使列表视图透明?如何更改列表视图背景颜色?

SwiftUI - 重音,前景色和色调之间的区别?

SwiftUI Textfield - 如何在编辑模式下设置文本字段的背景颜色以清除

更改 ScrollView SwiftUI 的背景颜色