SwiftUI - анимация просмотра непрозрачности в ZStack с помощью .easeInOut - PullRequest
1 голос
/ 02 мая 2020

У меня есть вид, расположенный поверх mapView (в ZStack), и я хочу иметь возможность увеличивать и уменьшать зеленый верхний вид с помощью модификатора анимации .easeInOut, примененного к непрозрачности вида. Как вы можете видеть в gif, он красиво исчезает, но внезапно исчезает.

enter image description here

Если я удаляю mapView, то все хорошо. Если я заменю mapView на простой Rectangle(), проблема вернется, поэтому я считаю, что это связано с 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, но не удалось найти предыдущую ссылку.

Ответы [ 2 ]

1 голос
/ 02 мая 2020

попробуйте это: -> только что добавил 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)
        }
    }
}

и прочитайте это:

Анимация перехода не работает в SwiftUI

1 голос
/ 02 мая 2020

Вот рабочий раствор. Протестировано с Xcode 11.4 / iOS 13.4.

demo

Как видно из демонстрации, наличие прозрачной метки не влияет на функциональность вида карты.

    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 body: some View {
    VStack {
        ZStack {
            MapView()
            VStack {              // << here !!
                if show {
                    LabelView()
                }
            }.transition(.opacity).animation(.easeInOut(duration: 1.0))
        }
        Button("Animate") {
            self.show.toggle()
        }.padding(20)
    }
}
...