【问题标题】:SwiftUI animating the width of RoundedRectangle from 0 to width onAppear?SwiftUI动画RoundedRectangle的宽度从0到宽度onAppear?
【发布时间】:2021-01-27 03:16:42
【问题描述】:

我以为我写得对,但 RoundedRectangle 没有动画......我错过了什么? ????

struct BarView: View {
    
    var progress: Double = 0.0
    
     var progressAnimation: Animation {
        Animation
            .linear
            .speed(0.5)
            .delay(0.02)
     }
    
    var body: some View {
        
        ZStack {
                ZStack(alignment: .leading) {
                    RoundedRectangle(cornerRadius: 12.0)
                        .fill(Color(.lightGray))
                        .opacity(0.1)
                        .frame(height: 15)
                        .overlay(GeometryReader { geometry in
                    RoundedRectangle(cornerRadius: 12.0)
                        .fill(getColorForBar(progress: progress))
                        .frame(width: getFillWidth(progress: progress, geometry: geometry), height: 15)
                        .animation(self.progressAnimation)
                         }, alignment: .leading)
                }
        }
    }

【问题讨论】:

    标签: ios swift animation swiftui


    【解决方案1】:

    这里有一些修改后的代码,适用于 Xcode 12.1 / iOS 14.1。所以问题可能出在使用位置或getFillWidth 函数中。

    struct TestBarView: View {
        @State private var value = 0.0
        var body: some View {
            BarView(progress: value)
                .onAppear {
                    value = 0.8
                }
        }
    }
    
    struct BarView: View {
        
        var progress: Double = 0.0
        
        var progressAnimation: Animation {
            Animation
                .linear
                .speed(0.5)
                .delay(0.02)
        }
        
        var body: some View {
            
            ZStack {
                ZStack(alignment: .leading) {
                    RoundedRectangle(cornerRadius: 12.0)
                        .fill(Color(.lightGray))
                        .opacity(0.1)
                        .frame(height: 15)
                        .overlay(GeometryReader { geometry in
                            RoundedRectangle(cornerRadius: 12.0)
                                .fill(Color.blue)
                                .frame(width: geometry.size.width * CGFloat(progress), height: 15)
                                .animation(self.progressAnimation)
                        }, alignment: .leading)
                }
            }
        }
    }
    

    【讨论】:

    • 我认为问题在于我将值从父级传递到子级到 Barview。因此,在您的示例中,如果我将值更改为 @State,因为值来自父级(即 @State),那么该值将永远不会改变。
    • 这是对概念的错误理解。 @State 包装器用于 internal 视图使用 - 你永远不能在外部修改它,它只初始化一次。要记住这一点,对此类属性使用 private 修饰符是一种很好的设计模式。
    猜你喜欢
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多