macOS 上的 SwiftUI - 无法使用平滑、居中的动画缩放 ProgressView

问题描述 投票:0回答:2

我想知道是否有人可以帮助我理解为什么下面的 SwiftUI 代码产生的动画有问题。这是代码:

struct ProgressViewAnimationGlitch: View {
    @State private var isShowingProgressView: Bool = false
    var body: some View {
        ZStack(alignment: .center) {
            if !isShowingProgressView {
                Circle()
                    .fill(Color.red)
                    .onTapGesture {
                        withAnimation {
                            isShowingProgressView = true
                        }
                    }
                    .transition(.scale)
            }
            
            if isShowingProgressView {
                ProgressView()
                    .transition(.scale)
            }
        }
        .frame(width: 100, height: 100, alignment: .center)
    }
}

当我说“故障”时,我的意思是

ProgressView
不仅从右下角滑入而不是从中心弹出,而且在我点击红色圆圈之后它似乎延迟了一会儿才开始它(不正确的)进入动画。

我尝试了很多变体(包括

.scaleEffect(_:)
修饰符),但无法让
ProgressView
按照我的意愿从中心平滑地放大和缩小。

谢谢!

animation swiftui progress-bar spinner visual-glitch
2个回答
0
投票
  1. 我的开发环境是 Xcode 14.3 / macOS Ventura 13.1
  2. 您的代码在 iOS 16.4 模拟器上运行良好。
  3. 只有在macOS上才会出现你说的问题,如下图删除
    .transition(.scale)
    ProgressView()
    即可解决。 (也可以改成
    .opacity
    .identity
    类型。)
struct ProgressViewAnimationGlitch: View {
    @State private var isShowingProgressView: Bool = false
    var body: some View {
        ZStack(alignment: .center) {
            if !isShowingProgressView {
                Circle()
                    .fill(Color.red)
                    .onTapGesture {
                        withAnimation {
                            isShowingProgressView = true
                        }
                    }
                    .transition(.scale)
            }
            
            if isShowingProgressView {
                ProgressView()
                    // .transition(.scale)  <-- 👀
            }
        }
        .frame(width: 100, height: 100, alignment: .center)
    }
}

0
投票

看起来当圆圈在此时间之前完成其动画缩放时,Progressview 已经处于其全尺寸视图中。将它放在缩放的圆圈上会显示图形故障。但是是的,如果你在模拟器上运行上面的代码可以正常工作,但是如果你在 Mac 上运行它就会失败。以上建议的解决方案也适用于我尝试过的。但据我了解,您必须使用具有自身价值的动画,如下面的解决方案。它适用于 iOS 和 Mac。希望能帮助到你。在 Xcode 14.3 上测试

struct ProgressViewAnimationGlitch: View {
    @State private var isShowingProgressView: Bool = false
    @State var scale = 0.1
    let animation = Animation.linear(duration: 0.5).repeatCount(1)
    var body: some View {
        ZStack(alignment: .center) {
            if !isShowingProgressView {
                Circle()
                    .fill(Color.red)
                    .onTapGesture {
                        withAnimation {
                            isShowingProgressView = true
                            withAnimation(animation) {
                                scale  = 1.0
                                }
                        }
                    }
                    .transition(.scale)
            }
            
            if isShowingProgressView {
                ProgressView()
                    .frame(alignment: .center)
                    .scaleEffect(scale)

            }
        }
        .frame(width: 100, height: 100, alignment: .center)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.