SwiftUI 与rotation3DEffect 动画冲突
Posted
技术标签:
【中文标题】SwiftUI 与rotation3DEffect 动画冲突【英文标题】:SwiftUI conflict with rotation3DEffect animation 【发布时间】:2020-11-05 02:39:39 【问题描述】:代码参考:https://github.com/amosgyamfi/swiftui-animation-library/blob/master/After%20WWDC2020/Parallax%203D/ios_3d_parallax.gif
当我改变状态 HorizontalAlignment 并在 VStack(alignment: HorizontalAlignment) 中使用它时,内容将从左移到中心。
我想通过点击按钮在中心和前导之间切换
当前效果:
预期效果:
import SwiftUI
struct ContentView: View
@State private var rotateIn3D = false
@State private var horizontalAlignment: HorizontalAlignment = .leading
let weatherBg = LinearGradient(gradient: Gradient(colors: [Color.blue, Color.white]), startPoint: .topLeading, endPoint: .bottomTrailing)
var body: some View
VStack
ZStack // Weather
VStack(alignment: horizontalAlignment)
Text("Wednesday")
Text("18°")
.font(.system(size: 44))
.fontWeight(.thin)
Spacer()
Image(systemName: "cloud.sun.fill")
Text("Partly Cloudy")
.frame(width: 150, height: 20, alignment: .leading)
Text("H:21° L:12°")
.padding()
.background(Color.blue)
.background(Color.yellow)
.cornerRadius(22)
.foregroundColor(.white)
.frame(width: 170, height: 170, alignment: .leading)
.rotation3DEffect(.degrees(rotateIn3D ? 12 : -12), axis: (x: rotateIn3D ? 90 : -45, y: rotateIn3D ? -45 : -90, z: 0))
.animation(Animation.easeInOut(duration: 2).repeatForever(autoreverses: true))
.onAppear()
rotateIn3D.toggle()
Button(action:
horizontalAlignment = .center
, label:
Text("Change Horizontal Alignment to center")
)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
.preferredColorScheme(/*@START_MENU_TOKEN@*/.dark/*@END_MENU_TOKEN@*/)
【问题讨论】:
【参考方案1】:只需根据每个状态的值制作动画即可。
使用 Xcode 12.1 / iOS 14.1 测试
// ... other code
.rotation3DEffect(.degrees(rotateIn3D ? 12 : -12), axis: (x: rotateIn3D ? 90 : -45, y: rotateIn3D ? -45 : -90, z: 0))
.animation(Animation.easeInOut(duration: 2).repeatForever(autoreverses: true),
value: rotateIn3D) // << here !!
.animation(.default, value: horizontalAlignment) // << here !!
.onAppear()
rotateIn3D.toggle()
【讨论】:
@Asperi:对我来说没有 .animation(.default, value: HorizontalAlignment) 对我来说没有必要【参考方案2】:这里:如你所愿
import SwiftUI
struct ContentView: View
@State private var rotateIn3D = false
var body: some View
VStack
ZStack
VStack
Text("Wednesday")
Text("18°")
.font(.system(size: 44))
.fontWeight(.thin)
Spacer()
Image(systemName: "cloud.sun.fill")
Text("Partly Cloudy")
Text("H:21° L:12°")
.frame(width: 150, height: 150)
.padding()
.background(Color.blue)
.background(Color.yellow)
.cornerRadius(22)
.foregroundColor(.white)
.frame(width: 170, height: 170, alignment: .leading)
.rotation3DEffect(.degrees(rotateIn3D ? 12 : -12), axis: (x: rotateIn3D ? 90 : -45, y: rotateIn3D ? -45 : -90, z: 0))
.animation(Animation.easeInOut(duration: 2).repeatForever(autoreverses: true))
.onAppear()
rotateIn3D.toggle()
更新:2.0.0 版
import SwiftUI
struct ContentView: View
@State var rotateIn3D = false
@State var alignmentToggle = false
let weatherBg = RadialGradient(gradient: Gradient(colors: [Color.blue, Color.white]), center: .center, startRadius: 30, endRadius: 200)
var body: some View
ZStack
VStack(alignment: alignmentToggle ? .leading : .center)
Text("Wednesday")
Text("18°").font(.system(size: 44)).fontWeight(.thin)
Spacer()
Image(systemName: "cloud.sun.fill")
Text("Partly Cloudy")
Text("H:21° L:12°")
.padding()
.frame(width: 170, height: 170)
.background(weatherBg)
.foregroundColor(.white)
.cornerRadius(22)
.shadow(color: Color.black.opacity(0.7), radius: 10, x: 0, y: 30)
.rotation3DEffect(.degrees(rotateIn3D ? 12 : -12), axis: (x: rotateIn3D ? 90 : -45, y: rotateIn3D ? -45 : -90, z: 0))
.animation( rotateIn3D ? Animation.easeInOut(duration: 2).repeatForever(autoreverses: true) : Animation.easeInOut(duration: 2))
.onAppear() rotateIn3D.toggle()
VStack
Spacer()
Button("alignment toggle")
rotateIn3D.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() + 2.1)
alignmentToggle.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() + 2.1)
rotateIn3D.toggle()
.font(.title)
.padding()
【讨论】:
当我更改状态horizontalAlignment
并在 VStack(alignment: horizontalAlignment)
中使用它时,问题仍然存在
我要动态改变ui
我真的不懂你!你问中心,我给了答案!您想通过点击按钮在中心和前导之间切换吗?请说明你想要什么。
是的,我想通过点击按钮在中心和前导之间切换以上是关于SwiftUI 与rotation3DEffect 动画冲突的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 与 Microsoft 的 Firebase 身份验证