【问题标题】:SwiftUI Animation Not Working When View Removed删除视图时 SwiftUI 动画不起作用
【发布时间】:2020-06-14 08:05:09
【问题描述】:

SwiftUI 动画视图移除不起作用

我正在为 SwiftUI 视图上的动画修饰符而苦苦挣扎。

我在 SwiftUI 中有一个带有 MKMapView ViewRepresentable 的映射函数。我有一个 带有两个控件的注释。此处列出的动画代码和 下面的 ComboDetailMapView 确实可以正确设置动画以显示 子视图 - 但我没有尝试过在视图被删除时对其进行动画处理。

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    if control == view.leftCalloutAccessoryView {
        //this animates in - but does NOT animate out - required here for ANY animation
        withAnimation(.easeInOut(duration: 1.0)) {
            parent.userDefaultsManager.showAddRemoveWaypointsView.toggle()
        }

    } else if control == view.rightCalloutAccessoryView {
        //this animates in - but does NOT animate out - required in this place
        withAnimation(.easeInOut(duration: 1.0)) {
            parent.userDefaultsManager.displayAddressView.toggle()
    }
    //...bunch more stuff
}

我正在制作动画的视图是一个简单的白色背景图像,具有不透明度变化 和一个警报样式的子视图。

struct DisplayAddressView: View {
    @ObservedObject var userDefaultsManager: UserDefaultsManager
    @Environment(\.presentationMode) var presentationMode

    var body: some View {

        ZStack {
            GeometryReader { geo in
                VStack {
                Image("PlainMask")
                    .resizable()
                    .frame(width: geo.size.width, height: geo.size.height + 20, alignment: .center)
                    .opacity(0.9)
                }//vstack
            }//geo reader

            RoundedRectangle(cornerRadius: 20)
                .fill(Color.blue).opacity(0.3)
                .frame(width: 300, height: 200)
            VStack {
                Button(action: {
                    //animation command does not work here
                    //withAnimation(.easeInOut(duration: 1.0)) {
                    self.userDefaultsManager.displayAddressView.toggle()
                }) {
                    VStack {
                        Text("Approximate Address")
                            //.font(.headline)
                            .foregroundColor(.primary)
                            .font(.system(size: 20) )
                            .multilineTextAlignment(.center)
                        Divider()
                        Text(self.userDefaultsManager.approximateAddress)
                            //.font(.headline)
                            .foregroundColor(.red)
                            .font(.system(size: 20) )
                            .multilineTextAlignment(.center)
                    }
                }
                .padding(.bottom)
                Divider()
                Button(action: {
                    //animation command does not work here
                    //withAnimation(.easeInOut(duration: 1.0)) {}
                    self.userDefaultsManager.displayAddressView.toggle()
                }) {

                    Text("Dismiss")
                        //.font(.headline)
                        .foregroundColor(.primary)
                        .font(.system(size: 20) )
                }
            }
        }//Zstack
    }//body
}

这是启动 DisplayAddressView 视图的视图:

struct ComboDetailMapView: View {

    @ObservedObject var userDefaultsManager: UserDefaultsManager
    var aTrip: Trip?

    var body: some View {
        ZStack {
            VStack {
                Text(aTrip?.name ?? "Unknown Map Name")
                    .padding(.top, -50)
                    .padding(.bottom, -20)
                DetailMapView(userDefaultsManager: userDefaultsManager, aTrip: aTrip)
                    .padding(.top, -20)
                Text(self.userDefaultsManager.tripTimeAndDistance)
                    .multilineTextAlignment(.center)
            }//vstack

            if userDefaultsManager.displayAddressView {
                DisplayAddressView(userDefaultsManager: userDefaultsManager)
                //this works to add slide to the other animation
                .transition(AnyTransition.opacity.combined(with: .slide))
                //this does not work for dismissal
                //.transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .slide), removal: .scale))
            }
        }//zstack
    }//body
} 

我也尝试过这个 SO 59064231 的想法。不高兴。

我承认动画视图的过程,因为你不能再附加修饰符 直接到视图仍然让我困惑。任何指导将不胜感激。 Xcode 11.3.1 (11C504)

【问题讨论】:

  • 基本上,如果有一个可复制和可重现的例子来处理会更容易......所以我建议分解为人们愿意帮助的可重现的例子

标签: ios xcode animation swiftui


【解决方案1】:

事实证明,如果您退后一步考虑一下我在这里需要的功能,我可以简单地使用三元组来控制视图的位置。不需要 if 语句来比较绑定,也不需要复杂的 .transition 协调。作为奖励,如果需要,不透明度也可以设置动画。

DisplayAddressView(userDefaultsManager: userDefaultsManager)
    .offset(x: userDefaultsManager.showAddressView ? 0 : 500)
    .animation(.easeInOut(duration: 1.0))

光滑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    • 1970-01-01
    相关资源
    最近更新 更多