SwiftUI视图显示和隐藏的transition动画
SwiftUI视图显示和隐藏的transition动画

SwiftUI视图显示和隐藏的transition动画

在 SwiftUI 中,transition 用于定义视图如何从屏幕上“进入”和“退出”。它常与 @State 和 if 条件配合,用于控制视图的显示和隐藏,同时可以实现精美的动画效果。

示例

.transition(.slide) // 使用滑动效果

基本用法

transition 定义视图在插入或移除时的动画方式。

import SwiftUI

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

    var body: some View {
        VStack {
            Button("Toggle View") {
                withAnimation {
                    isVisible.toggle()
                }
            }

            if isVisible {
                Rectangle()
                    .fill(Color.blue)
                    .frame(width: 100, height: 100)
                    .transition(.slide) // 使用滑动效果
            }
        }
    }
}

常见的内置 Transition 类型

1、.opacity:视图通过透明度渐入渐出

.transition(.opacity)

2、.slide:视图从屏幕边缘滑入或滑出

.transition(.slide)

3、.scale:视图通过缩放效果出现或消失

.transition(.scale)

4、.move(edge:):从指定的边缘移入或移出

.transition(.move(edge: .top))

5、.offset(x:y:):使用偏移量定义进入和退出动画

.transition(.offset(x:-100,y:100))

6、.asymmetric(insert:, remove:):为进入和移出分别设置动画

.transition(.asymmetric(insertion: .slide, removal: .opacity))

代码示例

示例 1:.opacity 和 .scale 组合

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

    var body: some View {
        VStack {
            Button("Toggle View") {
                withAnimation {
                    isVisible.toggle()
                }
            }

            if isVisible {
                Circle()
                    .fill(Color.green)
                    .frame(width: 100, height: 100)
                    .transition(.opacity.combined(with: .scale)) // 同时使用透明度和缩放
            }
        }
    }
}

效果:视图逐渐变大并淡入;移除时逐渐缩小并淡出。

示例 2:.move(edge:)

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

    var body: some View {
        VStack {
            Button("Toggle View") {
                withAnimation {
                    isVisible.toggle()
                }
            }

            if isVisible {
                Rectangle()
                    .fill(Color.orange)
                    .frame(width: 200, height: 100)
                    .transition(.move(edge: .leading)) // 从左边缘移入移出
            }
        }
    }
}

效果:视图从左侧滑入或滑出。

示例 3:.asymmetric(insert:, remove:)

asymmetric 允许为插入和移除视图指定不同的动画。

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

    var body: some View {
        VStack {
            Button("Toggle View") {
                withAnimation {
                    isVisible.toggle()
                }
            }

            if isVisible {
                RoundedRectangle(cornerRadius: 20)
                    .fill(Color.purple)
                    .frame(width: 200, height: 100)
                    .transition(.asymmetric(
                        insertion: .scale,        // 插入时缩放出现
                        removal: .move(edge: .bottom) // 移除时向下滑出
                    ))
            }
        }
    }
}

效果

视图插入时有缩放动画。

视图移除时从底部滑出。

自定义 Transition

除了内置的 transition,还可以定义自己的过渡动画,使用 .modifier() 方法。

自定义示例

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

    var body: some View {
        VStack {
            Button("Toggle View") {
                withAnimation {
                    isVisible.toggle()
                }
            }

            if isVisible {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 200, height: 100)
                    .transition(.customTransition) // 自定义过渡
            }
        }
    }
}

extension AnyTransition {
    static var customTransition: AnyTransition {
        AnyTransition.modifier(
            active: CustomModifier(offset: 300, opacity: 0),
            identity: CustomModifier(offset: 0, opacity: 1)
        )
    }
}

struct CustomModifier: ViewModifier {
    var offset: CGFloat
    var opacity: Double

    func body(content: Content) -> some View {
        content
            .offset(x: offset)
            .opacity(opacity)
    }
}

效果

插入时视图从屏幕外(x: 300)滑入并淡入。

移除时视图滑出屏幕并淡出。

添加 Transition 动画的条件

有时候,可能希望过渡动画仅在特定条件下生效,可以通过 if 或 .transaction 控制。

示例

struct ContentView: View {
    @State private var isVisible = false
    @State private var enableTransition = true

    var body: some View {
        VStack {
            Toggle("Enable Transition", isOn: $enableTransition)
                .padding()

            Button("Toggle View") {
                if enableTransition {
                    withAnimation {
                        isVisible.toggle()
                    }
                } else {
                    isVisible.toggle()
                }
            }

            if isVisible {
                Circle()
                    .fill(Color.blue)
                    .frame(width: 100, height: 100)
                    .transition(.scale)
            }
        }
    }
}

总结

transition 用于控制视图的进入和退出动画,与 if 条件和 withAnimation 配合。

内置的 .opacity、.slide、.scale 等常见效果可以直接使用。

使用 .asymmetric 和 .modifier() 进行组合和自定义,可以实现复杂的动画需求。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注