Проблема с анимацией смещения SwiftUI при подготовке нижнего листа

avatar
Batuhan Baran
8 августа 2021 в 19:07
179
1
2

Я хотел своими силами сделать нижний лист в SwiftUI, открываю его с помощью анимации, но у меня не работает анимация при закрытии, в чем причина? Интересно, увеличивается ли значение смещения с анимацией, есть ли проблема, когда оно уменьшается? Я не очень хорошо разбираюсь в SwiftUI, поэтому я не мог полностью понять проблему.

    struct ContentView: View {
    @State var isOpen = false
    @State var offset =  UIScreen.main.bounds.height / 3
    
    var body: some View {
        ZStack {
            Color.blue
                .ignoresSafeArea()
            
            Button(action: {
                self.isOpen.toggle()
            }, label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 25.0)
                        .foregroundColor(.black)
                    
                    Text("Open")
                        .font(.title2)
                        .fontWeight(.bold)
                        .foregroundColor(.white)
                }
            })
            .buttonStyle(DefaultButtonStyle())
            .frame(width: 300, height: 50, alignment: .center)
            
            if isOpen {
                GeometryReader { geometry in
                    VStack {
                        Spacer()
                        BottomSheet()
                            .frame(width: geometry.size.width,
                                   height: geometry.size.height / 3,
                                   alignment: .center)
                            .background(
                                Color.white
                            )
                            .offset(y: offset)
                            .onAppear(perform: {
                                withAnimation {
                                    self.offset = 0
                                }
                            })
                            .onDisappear(perform: {
                                withAnimation {
                                    self.offset = UIScreen.main.bounds.height / 3
                                }
                            })

                    }.ignoresSafeArea()

                }
            }
        }
    }
}

Нижний лист

  struct BottomSheet: View {
    var body: some View {
        Text("Hello, World!")
    }
}
Источник

Ответы (1)

avatar
RTXGamer
8 августа 2021 в 21:10
0

onDisappear вызывается при удалении представления, поэтому пользовательская анимация не работает:

struct ContentView: View {
    @State var isOpen = false
    
    var offset: CGFloat {
        isOpen ? 0 : UIScreen.main.bounds.height / 3
    }
    
    var body: some View {
        ZStack {
            Color.blue
                .ignoresSafeArea()
            
            Button(action: {
                self.isOpen.toggle()
            }, label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 25.0)
                        .foregroundColor(.black)
                    
                    Text("Open")
                        .font(.title2)
                        .fontWeight(.bold)
                        .foregroundColor(.white)
                }
            })
            .buttonStyle(DefaultButtonStyle())
            .frame(width: 300, height: 50, alignment: .center)
            
            GeometryReader { geometry in
                VStack {
                    Spacer()
                    BottomSheet()
                        .frame(width:geometry.size.width,
                               height: geometry.size.height / 3,
                               alignment: .center)
                        .background(
                            Color.white
                        )
                        .offset(y: offset)
                        .animation(.easeInOut(duration: 0.5))                            .transition(.move(edge: .bottom))
                }                            .edgesIgnoringSafeArea(.bottom)
            }
        }
    }
}