Animation SwiftUI-使用.easeInOut在ZStack中设置视图不透明度动画

Animation SwiftUI-使用.easeInOut在ZStack中设置视图不透明度动画,animation,swiftui,opacity,zstack,easeinout,Animation,Swiftui,Opacity,Zstack,Easeinout,我有一个位于地图视图顶部的视图(在ZStack中),希望能够将绿色的上视图淡入淡出,并将.easeInOut动画修改器应用于视图的不透明度。正如您在gif中看到的,它很好地淡入,但突然消失 如果我删除mapView,那么一切都很好。如果我用一个简单的Rectangle()替换mapView,那么问题又出现了,因此我认为它与ZStack有关,而不是与地图有关。有趣的是,我实际上使用的是Mapbox而不是MapKit(为了简单起见,在下面的代码中),而淡入淡出/突然消失的行为是相反的 import

我有一个位于地图视图顶部的视图(在ZStack中),希望能够将绿色的上视图淡入淡出,并将
.easeInOut
动画修改器应用于视图的不透明度。正如您在gif中看到的,它很好地淡入,但突然消失

如果我删除mapView,那么一切都很好。如果我用一个简单的
Rectangle()
替换mapView,那么问题又出现了,因此我认为它与ZStack有关,而不是与地图有关。有趣的是,我实际上使用的是Mapbox而不是MapKit(为了简单起见,在下面的代码中),而淡入淡出/突然消失的行为是相反的

import SwiftUI
import MapKit

struct ContentView: View {
    @State private var show = false

    var body: some View {
        VStack {
            ZStack {
                MapView()
                if show {
                    LabelView()
                        .transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
                }
            }
            Button("Animate") {
                self.show.toggle()
            }.padding(20)
        }
    }
}

struct MapView: UIViewRepresentable {
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.mapType = .standard
        return mapView
    }

    func updateUIView(_ uiView: MKMapView, context: Context) { }
}

struct LabelView: View {
    var body: some View {
        Text("Hi there!")
            .padding(10)
            .font(.title)
            .foregroundColor(.white)
            .background(RoundedRectangle(cornerRadius: 8).fill(Color.green).shadow(color: .gray, radius: 3))
    }
}
我已尝试使用替代动画代码,将
LabelView
转换替换为:

.transition(.opacity)
并将按钮代码更改为:

Button("Animate") {
    withAnimation(.easeInOut(duration: 1.0)) {
        self.show.toggle()
    }
}

但每次都会出现同样的行为。我猜这是一个SwiftUI错误,但找不到任何以前的参考。

这里是可行的解决方案。使用Xcode 11.4/iOS 13.4进行测试

正如在演示中所看到的,透明标签的存在并不影响地图视图的功能

    var body: some View {
        VStack {
            ZStack {
                MapView()
                LabelView().opacity(show ? 1 : 0)   // here !!
            }.animation(.easeInOut(duration: 1.0))

            Button("Animate") {
                self.show.toggle()
            }.padding(20)
        }
    }
另一种替代方法,实际上具有相同的视觉效果,就是将
LabelView
嵌入到容器中,并对其应用转换(必须保留一些内容以使视图消失)

var主体:一些视图{
VStack{
ZStack{
地图视图()

VStack{/试试这个:->刚刚添加了zIndex…其他一切都一样

struct ContentView: View {
    @State private var show = false

    var body: some View {
        VStack {
            ZStack {
                MapView().zIndex(0)
                if show {
                    LabelView()
                    .zIndex(1)
                        .transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
                }
            }
            Button("Animate") {
                self.show.toggle()
            }.padding(20)
        }
    }
}
并阅读以下内容:

struct ContentView: View {
    @State private var show = false

    var body: some View {
        VStack {
            ZStack {
                MapView().zIndex(0)
                if show {
                    LabelView()
                    .zIndex(1)
                        .transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
                }
            }
            Button("Animate") {
                self.show.toggle()
            }.padding(20)
        }
    }
}