【问题标题】:SwiftUI: Can't get the transition of a DetailView to a ZStack in the MainView to workSwiftUI:无法在 MainView 中将 DetailView 转换为 ZStack 工作
【发布时间】:2020-08-10 05:35:07
【问题描述】:

我在任何地方都找不到这个问题的答案,希望你们能帮助我。

我有一个包含一些内容的 MainView。按下一个按钮,我想打开一个 DetailView。我正在使用 ZStack 将 DetailView 分层,填充屏幕。

但是使用下面的代码我无法让它工作。 DetailView 在插入时没有过渡,在移除时停止。我尝试过手动设置和不设置 zIndex,以及自定义的 assymetricalTransition。无法让它发挥作用。有什么解决办法吗?

//MainView
@State var showDetail: Bool = false

var body: some View {
    ZStack {
        VStack {
            Text("Hello MainWorld")
            Button(action: {
                withAnimation(.spring()) {
                    self.showDetail.toggle()
                }
            }) {
                Text("Show detail")
            }
        }


        if showDetail {
            ContentDetail(showDetail: $showDetail)
                .transition(.move(edge: .bottom))
        }
    }
    .edgesIgnoringSafeArea(.all)
}

这里是 DetailView:

//DetailView

@Binding var showDetail: Bool    

var body: some View {
    VStack (spacing: 25) {
        Text("Hello, DetailWorld!")

        Button(action: { withAnimation(.spring()) {
            self.showDetail.toggle()
            }

        }) {
            Text("Close")
        }
        .padding(.bottom, 50)


    }
    .frame(width: UIScreen.main.bounds.width,
           height: UIScreen.main.bounds.height)
    .background(Color.yellow)
    .edgesIgnoringSafeArea(.all)

}

这段代码的结果是这样的:

我正在运行 Xcode 11.4.1,因此隐式动画似乎也不起作用。真的卡在这里,希望你们中的一个可以帮助我!谢谢:)

【问题讨论】:

    标签: swift animation swiftui transition z-index


    【解决方案1】:

    这里有一个解决方案。使用 Xcode 11.4 / iOS 13.4 测试。

    struct MainView: View {
        @State var showDetail: Bool = false
    
        var body: some View {
            ZStack {
                Color.clear // extend ZStack to all area
                VStack {
                    Text("Hello MainWorld")
                    Button(action: {
                            self.showDetail.toggle()
                    }) {
                        Text("Show detail")
                    }
                }
    
                if showDetail {
                    DetailView(showDetail: $showDetail)
                        .transition(AnyTransition.move(edge: .bottom))
                }
            }
            .animation(Animation.spring())  // one animation to transitions
            .edgesIgnoringSafeArea(.all)
        }
    }
    
    struct DetailView: View {
        @Binding var showDetail: Bool
    
        var body: some View {
            VStack (spacing: 25) {
                Text("Hello, DetailWorld!")
    
                Button(action: {
                    self.showDetail.toggle()
                }) {
                    Text("Close")
                }
                .padding(.bottom, 50)
    
    
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity) // fill in container
            .background(Color.yellow)
        }
    }
    

    【讨论】:

    • 感谢您的回复。我之前已经尝试过,但是使用此解决方案时,DetailCard 会立即进入后台,如果我尝试使用 zIndex(1) 手动将其设置为最前面,则应用程序会崩溃。有什么想法吗?
    • @Wood,我不知道DetailCard 是什么——问题材料中没有这样的观点。正如您在演示中看到的那样,DetailView 在两个方向转换中都处于首位,这就是我没有使用 zIndex 的原因,但是,无论如何,如果您在我的代码中添加 DetailView(showDetail: $showDetail).transition(AnyTransition.move(edge: .bottom)).zIndex(1) 就不会崩溃。
    • 对不起,我的意思是 DetailView,我的错。如果您使用慢速动画运行初始答案或将颜色设置为 .white 而不是 .clear,则它是可见的。使用 .zIndex(1) 修饰符它在您第一次按下按钮时可以正常工作,但如果您相对较快地再次按下它,应用程序将会崩溃。
    • 仅供参考,Asperi 的回答对我有用,只要您在 cmets 中设置上述 zIndex。
    • 如果其他人遇到崩溃,Wood 正在描述为我解决的问题是将我的较高 Z 索引视图置于我的 body 属性中的另一个视图之上。
    猜你喜欢
    • 1970-01-01
    • 2022-08-15
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多