SwiftUI中的动画日期更改

时间:2020-10-29 12:42:43

标签: animation swiftui

我正在努力创建日期值不断变化的动画。下面是一个简化的示例。当日期从其原始值更新为新值时,它旨在通过更改值来更新“文本”视图。帮助将不胜感激!

struct DateAnimationView: View {

    @State var date = Date()

    typealias AnimatableData = Date

    var animatableData: Date{
        get{date}
        set{date = newValue}
    }

    var body: some View {
        VStack{
            Text(date, style: .time)
                .padding()
            
            Button(action:{
                withAnimation(.linear(duration: 3.0)){
                    date.addTimeInterval(60 * 60 * 3)
                }
            }){
                Text("Add 3 hours")
            }
                .padding()
            Spacer()
        }
    }
}

另一种尝试也失败了:

struct InnerView: View {
    var date: Date
    var interval: TimeInterval
        
    typealias AnimatableData = TimeInterval
    
    var animatableData: TimeInterval{
        get{interval}
        set{interval = newValue}
    }
    
    var body: some View{
        Text(date.addingTimeInterval(interval), style: .time)
    }
}

struct DateAnimationView: View{
    @State var isOn: Bool = false
    var body: some View{
        VStack{
            InnerView(date: Date(), interval: isOn ? 60*60*3 : 0)
            Button(action:{
                isOn.toggle()
            }){
                Text("Go")
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

基本思想是您需要为要设置动画的组件指定ID。 SwiftUI使用此ID来了解重绘时是同一组件还是新组件。如果是新组件,它将删除旧组件,并在动画中添加新组件。下面的代码实现了动画。

struct DateAnimationView: View {
    @State var date = Date()

    typealias AnimatableData = Date

    var animatableData: Date{
        get{date}
        set{date = newValue}
    }

    var body: some View {
        VStack{
            Text(date, style: .time)
                .padding()
                .id(String(date.hashValue))
            
            Button(action:{
                withAnimation(.linear(duration: 3.0)){
                    date.addTimeInterval(60 * 60 * 3)
                }
            }){
                Text("Add 3 hours")
            }
                .padding()
            Spacer()
        }
    }
}

解决方案posted here解决了类似的问题。