当出现在 ZStack 中时,SwiftUI 动画视图出现奇怪的过渡
SwiftUI animated view weird transition when appears inside ZStack
我对动画加载视图的行为有疑问。网络调用时显示加载视图。我的 viewModel 中有一个 isLoading @Published var,并且 ActivityIndicator 显示在我视图中的 ZStack 中。 Activityindicator 是一个自定义视图,我在其中为修剪过的圆制作动画 - 旋转它。每当 activity 指示器显示在我的 mainView 中时,它在出现时都会有一个奇怪的过渡 - 它从左上角过渡到视图的中心。有谁知道为什么会这样?我将结构与代码和 3 张图片与行为联系起来。
活动指标:
struct OrangeActivityIndicator: View {
var style = StrokeStyle(lineWidth: 6, lineCap: .round)
@State var animate = false
let orangeColor = Color.orOrangeColor
let orangeColorOpaque = Color.orOrangeColor.opacity(0.5)
init(lineWidth: CGFloat = 6) {
style.lineWidth = lineWidth
}
var body: some View {
ZStack {
CircleView(animate: $animate, firstGradientColor: orangeColor, secondGradientColor: orangeColorOpaque, style: style)
}.onAppear() {
self.animate.toggle()
}
}
}
struct CircleView: View {
@Binding var animate: Bool
var firstGradientColor: Color
var secondGradientColor: Color
var style: StrokeStyle
var body: some View {
Circle()
.trim(from: 0, to: 0.7)
.stroke(
AngularGradient(gradient: .init(colors: [firstGradientColor, secondGradientColor]), center: .center), style: style
)
.rotationEffect(Angle(degrees: animate ? 360 : 0))
.transition(.opacity)
.animation(Animation.linear(duration: 0.7) .repeatForever(autoreverses: false), value: animate)
}
}
该视图用于 :
struct UserProfileView: View {
@ObservedObject var viewModel: UserProfileViewModel
@Binding var lightMode: ColorScheme
var body: some View {
NavigationView {
ZStack {
VStack(alignment: .center, spacing: 12) {
HStack {
Text(userProfileEmail)
.font(.headline)
.foregroundColor(Color(UIColor.label))
Spacer()
}.padding(.bottom, 16)
SettingsView(userProfile: $viewModel.userProfile, isDarkMode: $viewModel.isDarkMode, lightMode: $lightMode, location: viewModel.locationManager.address, viewModel: viewModel)
ButtonsView( userProfile: $viewModel.userProfile)
Spacer()
}.padding([.leading, .trailing], 12)
if viewModel.isLoading {
OrangeActivityIndicator()
.frame(width: 40, height: 40)
// .animation(nil)
}
}
}
}
}
我也试过动画 nil 但它似乎不起作用。
以下是图片:
这是一个可能的解决方案 - 将其 放在 NavigationView
之上。使用 Xcode 12.4 / iOS 14.4
测试
NavigationView {
// .. your content here
}
.overlay( // << here !!
VStack {
if isLoading {
OrangeActivityIndicator()
.frame(width: 40, height: 40)
}
}
)
我对动画加载视图的行为有疑问。网络调用时显示加载视图。我的 viewModel 中有一个 isLoading @Published var,并且 ActivityIndicator 显示在我视图中的 ZStack 中。 Activityindicator 是一个自定义视图,我在其中为修剪过的圆制作动画 - 旋转它。每当 activity 指示器显示在我的 mainView 中时,它在出现时都会有一个奇怪的过渡 - 它从左上角过渡到视图的中心。有谁知道为什么会这样?我将结构与代码和 3 张图片与行为联系起来。 活动指标:
struct OrangeActivityIndicator: View {
var style = StrokeStyle(lineWidth: 6, lineCap: .round)
@State var animate = false
let orangeColor = Color.orOrangeColor
let orangeColorOpaque = Color.orOrangeColor.opacity(0.5)
init(lineWidth: CGFloat = 6) {
style.lineWidth = lineWidth
}
var body: some View {
ZStack {
CircleView(animate: $animate, firstGradientColor: orangeColor, secondGradientColor: orangeColorOpaque, style: style)
}.onAppear() {
self.animate.toggle()
}
}
}
struct CircleView: View {
@Binding var animate: Bool
var firstGradientColor: Color
var secondGradientColor: Color
var style: StrokeStyle
var body: some View {
Circle()
.trim(from: 0, to: 0.7)
.stroke(
AngularGradient(gradient: .init(colors: [firstGradientColor, secondGradientColor]), center: .center), style: style
)
.rotationEffect(Angle(degrees: animate ? 360 : 0))
.transition(.opacity)
.animation(Animation.linear(duration: 0.7) .repeatForever(autoreverses: false), value: animate)
}
}
该视图用于 :
struct UserProfileView: View {
@ObservedObject var viewModel: UserProfileViewModel
@Binding var lightMode: ColorScheme
var body: some View {
NavigationView {
ZStack {
VStack(alignment: .center, spacing: 12) {
HStack {
Text(userProfileEmail)
.font(.headline)
.foregroundColor(Color(UIColor.label))
Spacer()
}.padding(.bottom, 16)
SettingsView(userProfile: $viewModel.userProfile, isDarkMode: $viewModel.isDarkMode, lightMode: $lightMode, location: viewModel.locationManager.address, viewModel: viewModel)
ButtonsView( userProfile: $viewModel.userProfile)
Spacer()
}.padding([.leading, .trailing], 12)
if viewModel.isLoading {
OrangeActivityIndicator()
.frame(width: 40, height: 40)
// .animation(nil)
}
}
}
}
}
我也试过动画 nil 但它似乎不起作用。
以下是图片:
这是一个可能的解决方案 - 将其 放在 NavigationView
之上。使用 Xcode 12.4 / iOS 14.4
NavigationView {
// .. your content here
}
.overlay( // << here !!
VStack {
if isLoading {
OrangeActivityIndicator()
.frame(width: 40, height: 40)
}
}
)