如何在SwiftUI中为视图实现自定义过渡

时间:2019-09-06 15:27:02

标签: swift swiftui

我正在尝试实现一个过渡,该过渡使我的视线从一侧变小而逐渐消失。苹果已经提供了一些转换,但是如何自定义这些转换?附言我正在使用.transition修饰符。

2 个答案:

答案 0 :(得分:1)

您可以按以下方式制作类型为AnyTransition的计算变量:

static var moveAndFade: AnyTransition {
    let insertion = AnyTransition.move(edge: .trailing)
        .combined(with: .opacity)
    let removal = AnyTransition.scale
        .combined(with: .opacity)
    return .asymmetric(insertion: insertion, removal: removal)
}

您可能想查看Apple的tutorial series

答案 1 :(得分:0)

我想指出的是,过渡动画存在一个错误。您应该可以通过这种方式获得想要的东西:

struct ContentView: View {
    @State private var showView = false

    private var slideAndScale: AnyTransition {
        let insertion = AnyTransition.move(edge: .trailing)
        let removal = AnyTransition.scale
        return .asymmetric(insertion: insertion, removal: removal)
    }

    var body: some View {
        ZStack {
            Color.green
            if showView {
                Color.yellow
                    .transition(slideAndScale)
            }            
            Button(action: {
                withAnimation {
                    self.showView.toggle()
                }
            }) {
                self.showView ? Text("HIDE VIEW") : Text("SHOW VIEW")
            }
        }
    }
}

Color.yellow是使用自定义动画进出的视图。但是,如果您复制粘贴此代码,则会发现删除动画(在本例中为缩放动画)将无法工作。这是SwiftUI的错误。要解决此问题,有一种解决方法:

struct ContentView: View {
    @State private var showView = false

    private var slideAndScale: AnyTransition {
        let insertion = AnyTransition.move(edge: .trailing)
        let removal = AnyTransition.scale
        return .asymmetric(insertion: insertion, removal: removal)
    }

    var body: some View {
        ZStack {
            Color.green
            VStack {
                if showView {
                    Color.yellow
                        .transition(slideAndScale)
                }
            }
            Button(action: {
                withAnimation {
                    self.showView.toggle()
                }
            }) {
                self.showView ? Text("HIDE VIEW") : Text("SHOW VIEW")
            }
        }
    }
}

if showView中嵌入VStack块,并且删除动画将按预期运行。