试图用动画背景渐变来愚弄。当切换动画时,它会改变结束半径。 每当我合并移动整个 VStack 的动画(下面的 gif)时,它就会产生奇怪的行为。
我尝试将堆栈放入 ZStack 中,认为这将是一个解决方案,但最终结果仍然相同。
好奇到底是什么导致了这种行为
struct LandingPage: View {
@AppStorage("signedIn") var signedIn = false
@Environment (\.dismiss) var dismiss
@StateObject var vm = DashboardLogic()
@State private var animateGradient = false
@ViewBuilder
var body: some View {
if(signedIn){
// Text("Random Page")
}
else{
NavigationView{
VStack{
Image("bodybuilding-1") // << main image
.resizable()
.scaledToFit()
.frame(width:150, height:150)
//.renderingMode(.template)
.foregroundColor(.black)
.padding(.top, 200)
Text("Welcome to Meal Journal")
.font(.title)
.padding()
.offset(y:-25) // << adjusts title
VStack{
NavigationLink(destination:dummyPage() .navigationBarHidden(true),
label:{
Text("Get Started").fontWeight(.bold)
.frame(minWidth: 0, maxWidth: 200)
.padding(10)
.foregroundColor(.white)
//draw rectange around buttons
.background(
RoundedRectangle(cornerRadius: 20)
.fill(
LinearGradient(
colors: [.orange, .yellow],
startPoint: .topLeading,
endPoint: .bottomTrailing
)))
})
NavigationLink(destination: DummyPage().navigationBarHidden(true), label: {
Text("Login").fontWeight(.semibold)
.frame(minWidth:0, maxWidth: 200)
.padding(10)
.foregroundColor(.black)
.overlay( RoundedRectangle(cornerRadius: 25)
.stroke(Color.gray, lineWidth: 3)
)
})
.padding()
}
Rectangle()
.frame(height: 0)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
}
//.background(Color.purple)
.background(RadialGradient(gradient: Gradient(colors: [.yellow, .green]), center: .center, startRadius: 312, endRadius: animateGradient ? 100 : 450))
.onAppear {
DispatchQueue.main.async {
withAnimation(.linear(duration: 2.0).repeatForever(autoreverses: true)) {
animateGradient.toggle()
}
}
}
}
}
}
}
我没有仔细检查你的整个代码,但可能有帮助的一件事是记住背景是它自己的视图,所以你可以(并且经常必须)将修饰符应用于背景视图本身。因此,不要将父视图上的
.onAppear
添加到背景视图中,即:
var backgroundView: some View {
RadialGradient(gradient: Gradient(colors: [.yellow, .green]), center: .center, startRadius: 312, endRadius: animateGradient ? 100 : 450)
.onAppear {
withAnimation(.linear(duration: 2.0).repeatForever(autoreverses: true)) {
animateGradient.toggle()
}
}
}
}
然后父视图简单地使用背景视图:
VStack {
Image("bodybuilding-1")
...
}
.background(backgroundView)
游乐场示例:
struct AnimatedBackgroundView: View {
@State private var animateGradient = false
@State var scale = 1.0
var body: some View {
VStack {
Text("Hello")
Button("Do it", action: {})
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity
)
.scaleEffect(scale)
.background(backgroundView)
}
var backgroundView: some View {
RadialGradient(gradient: Gradient(colors: [.yellow, .green]), center: .center, startRadius: 312, endRadius: animateGradient ? 100 : 450)
.onAppear {
withAnimation(.linear(duration: 2.0).repeatForever(autoreverses: true)) {
animateGradient.toggle()
}
}
}
}
struct ContentView: View {
var body: some View {
AnimatedBackgroundView()
.frame(
width: 500,
height: 600
)
}
}
PlaygroundPage.current.setLiveView(ContentView())
但就像我说的:我没有调查你的整个代码,所以也许其他一些问题会阻止它工作
您应该将动画设置为任务 {} 而不是 onAppear。使用此动画也可以代替整个视图。
@State var animateGradient = false
LinearGradient(colors: [.purple, .yellow], startPoint: animateGradient ? .topTrailing : .bottomTrailing, endPoint: animateGradient ? .bottomLeading : .topTrailing)
.ignoresSafeArea()
.frame(width: 200, height: 200)
.task {
withAnimation(.linear(duration: 5.0).repeatForever(autoreverses: true)) {
animateGradient.toggle()
}
}