gpt4 book ai didi

ios - 嵌入另一个 View 时,SwiftUI 动画不起作用

转载 作者:行者123 更新时间:2023-12-01 21:47:30 25 4
gpt4 key购买 nike

我做了一个可重复使用的圆形进度条。我申请了repeatForever动画以使其保持旋转,但仅在直接与 @State 或 @Published 变量一起使用时才有效,并且在嵌入另一个 View 时无效。

Reusable RingView. Which is a circular progress bar


struct RingView: View {
private let percent: CGFloat = 80 // Keeping it fixed 80 for test purpose
var color = Color.primaryLightColor // Some random color
@Binding var show: Bool

var body: some View {
ZStack {
GeometryReader { bounds in

Circle()
.trim(from: self.show ? self.progress : 1, to: 1)
.stroke(
LinearGradient(gradient: Gradient(colors: [self.color]), startPoint: .topTrailing, endPoint: .bottomLeading),
style: StrokeStyle(lineWidth: self.lineWidth(width: bounds.size.width), lineCap: .round, lineJoin: .round, miterLimit: .infinity, dash: [20, 0], dashPhase: 0)
)
.rotationEffect(Angle(degrees: 90))
.animation(.none)
.frame(width: bounds.size.width, height: bounds.size.height)
}
}
.rotationEffect(.degrees(show ? 360.0 : 0.0))
.animation(show ? Animation.linear(duration: 1.0).repeatForever(autoreverses: false) : .none)
}

func multiplier(width: CGFloat) -> CGFloat {
width / 44
}

func lineWidth(width: CGFloat) -> CGFloat {
5 * self.multiplier(width: width)
}

var progress: CGFloat {
1 - (percent / 100)
}
}

Progress Button. It uses the RingView above. A general use case is to show animation when doing a long background task.

The RingView animation doesn't work in this ProgressButton


struct ProgressButton: View {
var action: () -> Void
var image: Image? = nil
var text: String = ""
var backgroundColor: Color = Color.blue
var textColor: Color = .white
@Binding var showProgress: Bool

var body: some View {
Button(action: action) {
HStack {
if showProgress {
RingView(color: textColor, show: self.$showProgress)
.frame(width: 25, height: 25)
.transition(.scale)
.animation(.Spring())
} else {
image?
.renderingMode(.original)
.resizable()
.frame(width: 25, height: 25)
}
Text(text)
.font(.headline)
.foregroundColor(textColor)
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 50, alignment: .center)
.background(backgroundColor)
.clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
}.buttonStyle(PlainButtonStyle())
}
}

When RingView animation works. When I use it directly as below.


struct LoginView: View {
@State var showProgress = true
var body: some View {
VStack {

// WORKING
RingView(show: self.$showProgress)
.frame(width: 25, height: 25)

// NOT WORKING
ProgressButton(action: {
self.showProgress = true
}, image: Image("password-lock"), text: "Login", backgroundColor: .blue, showProgress: self.showProgress)
}
}
}

I think I'm doing some mistake understanding how @Binding and @State are working.

最佳答案

动画在状态 上激活更改 .在提供的代码中没有任何变化,所以根本没有动画。

以下是主要更改,因此我使它起作用。使用 Xcode 11.4/iOS 13.4 测试(有一些缺少自定义依赖项的复制)

demo

1) 关闭初始动画

struct LoginView: View {
@State var showProgress = false

// ... other code

// no model provided so used same state for progress
ProgressButton(action: {
self.showProgress.toggle() // << activate change !!!
}, image: Image("password-lock"), text: L.Login.LoginSecurely, backgroundColor: self.isLoginButtonEnabled ? Color.primaryLightColor : Color.gray, showProgress: $showProgress)


2)在进度按钮内增加内环激活状态;用于隐藏/取消隐藏和激活的相同状态再次不起作用,因为当环出现时没有变化(已经是真的)所以环没有被激活
@State private var actiavteRing = false     // << here !!
var body: some View {
Button(action: action) {
HStack {

if showProgress {
RingView(color: textColor, show: self.$actiavteRing) // !!
.frame(width: 25, height: 25)
.transition(.opacity)
.animation(.spring())
.onAppear { self.actiavteRing = true } // <<
.onDisappear { self.actiavteRing = false } // <<

3)在环固定动画停用以避免累积效应(.none在这里不起作用),所以
.rotationEffect(.degrees(show ? 360.0 : 0.0))
.animation(show ? Animation.linear(duration:
1.0).repeatForever(autoreverses: false) : .default) // << here !!

关于ios - 嵌入另一个 View 时,SwiftUI 动画不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62070658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com