繁体   English   中英

新的 SwiftUI/iOS 15.0 .animation 无法按预期工作

[英]New SwiftUI/iOS 15.0 .animation not working as intended

我有一个自定义警报,我试图在演示时从屏幕顶部向下滑动。 我正在为 iOS 15 使用过渡和新的 .animation 修饰符:

import SwiftUI

struct SlideOverAlert: View {
    var text: String
    @Binding var isPresented: Bool
    var dismissAction: () -> Void
    
    var body: some View {
        if isPresented {
            ZStack {
                Rectangle()
                    .edgesIgnoringSafeArea(.top)
                    .frame(height: 80)
                    .foregroundColor(.orange)
                HStack {
                    Text(text)
                    Spacer()
                    Button(action: dismissAction) {
                        Image(systemName: "xmark")
                    }
                }
                .foregroundColor(.white)
                .padding()
            }
            .transition(.move(edge: isPresented ? .top : .bottom))
            .animation(.default, value: isPresented)
        }
    }
}

我的代码不起作用。 我不明白为什么...

这是我的预览代码:

struct SlideOverAlert_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
    
    struct ContentView: View {
        @State var alertIsPresented = true
        
        var body: some View {
            GeometryReader { _ in
                ZStack(alignment: .top) {
                    VStack {
                        Spacer()
                        Button(action: { alertIsPresented.toggle() }) {
                            Text("Toggle")
                        }
                        Spacer()
                    }
                    SlideOverAlert(
                        text: "That isn't going to work",
                        isPresented: $alertIsPresented
                    ) {
                        alertIsPresented.toggle()
                    }
                }
            }
        }
    }
}

如果您正在尝试构建自定义警报,我建议您使用新的fullScreenCover (IOS 14+)。 在您的预览/内容视图中,它看起来像这样:

// Attach the custom Alert to the view, bound to our state variable
.fullScreenCover(isPresented: $alertIsPresented) {
     SlideOverAlert()
}

这样,您无需将状态变量传递给SliderOverAlert ,然后在SlideOverAlert您就可以对@Environment演示模式的包装值调用dismiss()以关闭视图。 干净多了。 如果您需要保持背景清晰,请参阅此答案 也就是说,这些建议不会产生您正在寻找的向下滑动效果。 如果你对这种效果死心塌地,我可能会建议以下之一。 过渡在这里似乎不是最好的解决方案。 A.使用MatchedGeometryEffect在您尝试显示的视图的两个不同变体之间设置动画。 如果您试图让包括按钮在内的所有内容都平滑地动画,这可能更可取,因为MatchedGeometryEffect在转换后的视图之间保持成比例的间距。 B.保持代码.offset(x: 0, y: isPresented ? 0 : -1000) ,但删除if语句并将.offset(x: 0, y: isPresented ? 0 : -1000) .transition(行替换为以下内容: .offset(x: 0, y: isPresented ? 0 : -1000) 。但理想情况下,使用GeometryReader来确定您的偏移量而不是像 1000 这样的原始值。这应该会导致您的视图以编程方式进出动画,代价是视图始终在那里,即使它不在视线范围内。不过,与A.不同的是,视图将始终保持静态这部动画。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM