SwiftUI 教程

SwiftUI - 主页 SwiftUI - 概览 SwiftUI 与 UIkit

SwiftUI 环境

SwiftUI - 环境设置 SwiftUI - 基本组件 SwiftUI - 构建第一个应用程序

SwiftUI 视图

SwiftUI - 视图 SwiftUI - 自定义文本视图 SwiftUI - 自定义图像视图 SwiftUI - 堆栈

SwiftUI 绘制形状

SwiftUI - 形状 SwiftUI - 绘制线条 SwiftUI - 绘制矩形 SwiftUI - 绘制圆角矩形 SwiftUI - 绘制三角形 SwiftUI - 绘制圆形 SwiftUI - 绘制星形 SwiftUI - 绘制多边形 SwiftUI - 绘制饼图 SwiftUI - 使用内置形状

SwiftUI - 文本

SwiftUI - 文本视图 SwiftUI - 文本输入和输出

SwiftUI - 颜色

SwiftUI - 颜色 SwiftUI - 颜色选择器 SwiftUI - 渐变 SwiftUI - 调整颜色

SwiftUI - 效果

SwiftUI - 效果 SwiftUI - 混合效果 SwiftUI - BLur 效果 SwiftUI - 阴影效果 SwiftUI - 悬停效果

SwiftUI - 动画

SwiftUI - 动画 SwiftUI - 创建动画 SwiftUI - 创建显式动画 SwiftUI - 多个动画 SwiftUI - 过渡 SwiftUI - 不对称过渡 SwiftUI - 自定义过渡

SwiftUI - 图像

SwiftUI - 图像 SwiftUI - 图像作为背景 SwiftUI - 旋转图像 SwiftUI - 媒体

SwiftUI - 视图布局

SwiftUI - 视图布局 SwiftUI - 视图大小 SwiftUI - 视图间距 SwiftUI - 视图填充

SwiftUI - UI 控件

SwiftUI - UI 控件 SwiftUI - 按钮 SwiftUI - 复选框 SwiftUI - 菜单栏 SwiftUI - 工具栏 SwiftUI - 搜索栏 SwiftUI - 文本字段 SwiftUI - 滑块 SwiftUI - 切换 SwiftUI - 选择器 SwiftUI - 菜单

SwiftUI - 列表 &表格

SwiftUI - 列表 SwiftUI - 静态列表 SwiftUI - 动态列表 SwiftUI - 自定义列表 SwiftUI - 表格

SwiftUI - 表单

SwiftUI - 表单 SwiftUI - 在部分中拆分表单

SwiftUI - 事件处理

SwiftUI - 事件处理 SwiftUI - 手势 SwiftUI - 剪贴板 SwiftUI - 拖放 SwiftUI - 焦点 SwiftUI - 警报

SwiftUI - 杂项

SwiftUI - 容器 SwiftUI - 导航 SwiftUI - 通知 SwiftUI - 跨平台 UI SwiftUI - 数据 SwiftUI - 可访问性

SwiftUI - 框架集成

SwiftUI - 框架集成 SwiftUI - 与 UIKit 交互 SwiftUI - 创建 macOS 应用

SwiftUI 有用资源

SwiftUI - 有用资源 SwiftUI - 讨论


SwiftUI - 动画

动画是在视图状态发生变化时对屏幕上的视图进行动画处理的过程。它可以通过直观地反映视图中的变化来创建有吸引力的用户界面。因此,在本章中,我们将学习 SwiftUI 中动画的基础知识。

SwiftUI 中的动画

SwiftUI 对动画提供了良好的支持。借助动画,当视图状态发生变化时,我们可以轻松地在视图、组件或布局中创建流畅的视觉过渡。由于 SwiftUI 的声明式方法,我们可以为大小、颜色、不透明度、位置等属性设置动画,以响应视图状态的变化。

在 SwiftUI 中,我们可以使用以下方法创建动画 −

  • withAnimation(_:_:_) 方法:用于创建基于状态的动画。它允许您指定动画类型,并在状态变量改变其状态时执行动画。

  • animation(:value:) 方法:用于将动画插入特定视图,意味着当其状态被修改时,它会自动为指定视图的更改制作动画。

SwiftUI 中的动画类型

SwiftUI 支持以下类型的动画:

  • 隐式动画:此动画为视图提供预定义动画。因此,每当状态发生变化时,视图都会进行动画处理,它会自动运行,这意味着我们不需要指定动画的每一帧。这种类型的动画是通过使用 .animation() 方法实现的。

  • 显式动画:它用于创建仅更改给定视图内存在的指定属性的动画。我们可以借助 withAnimation() 方法实现显式动画。它为我们提供了对动画的更多控制。

  • 动画曲线:它提供了各种类型的动画曲线,例如 .easeIn、.easeOut、.easeInOut 和 .linear。它们通常用于控制动画视图的节奏。

  • 弹簧动画:它是一种用于创建弹簧运动的特殊动画类型。

  • 重复动画:它是一种动画类型,用于创建重复一定次数的动画。

  • 状态驱动动画:众所周知,在 SwiftUI 中,动画是通过更改 @State 或其他动态属性来触发的,因此每当状态变量的值发生变化时,视图的相应属性都会更新,并且转换会变成动画。

使用动画的好处

以下是使用动画将获得的一些主要好处 −

  • 动画增强了应用程序的可用性通过创建更清晰、更具交互性的应用界面。

  • 动画为用户提供对其操作的即时、清晰的响应,并减少任何混淆。

  • 应用程序中精心设计的动画可以增强用户参与度。

  • 动画可以帮助开发人员将更多注意力放在应用程序的重要部分。

  • 动画在状态之间移动时提供更平滑的过渡效果。

SwiftUI 中的嵌套动画

SwiftUI 借助 withAnimation() 方法支持嵌套动画。使用这个,我们可以将多个动画应用于视图。我们还可以通过嵌套两个或多个动画来创建特殊效果。

语法

以下是语法 −

func animation<V>(_animation:Animation?,
    value: V) -> some View where V : Equatable

示例

以下 SwiftUI 程序用于创建嵌套动画。这里外层的 withAnimation() 负责圆圈的缩放,内层的 withAnimation() 负责颜色变化。

import SwiftUI

struct ContentView: View {
   @State private var scale = false
   @State private var color = false

   var body: some View {
      VStack{
         Circle()
            .stroke(color ? Color.blue: Color.red, lineWidth: 6)
            .frame(width: 160)
            .scaleEffect(scale ? 1.7 : 1.1)
            .padding(10)
         Button("Click"){
            withAnimation(.easeInOut(duration: 8.0)){
               scale.toggle()
               withAnimation(.easeInOut(duration: 1.1)){
                  color.toggle()
               }
            }
         }.font(.title2)
      }
   }
}

#Preview {
   ContentView()
}

输出

Animation

SwiftUI 中的时序曲线

时序曲线用于借助不同的时序阶段(例如开始、中间和结束)来自定义动画的速度。它允许使用我们的运行方式在屏幕上移动动画。为了控制动画的速度,SwiftUI 提供了一个名为timingCurve()的内置修饰符。timingCurve() 修饰符根据给定的点为创建的动画设置动画。

语法

以下是语法 −

static func timingCurve(
   _ p1x: Double,
   _ p1y: Double,
   _ p2x: Double,
   _ p2y: Double,
   duration: TimeInterval = 0.35
) -> Animation

参数

以下是参数 −

  • p1x: 表示曲线控制点的第一个 x 坐标。

  • p1y: 表示曲线控制点的第一个 y 坐标。

  • p1x: 表示曲线控制点的第二个 x 坐标。

  • p1y: 表示曲线控制点的第二个 y 坐标。

  • duration: 表示动画的持续时间(以秒为单位)。

示例

以下 SwiftUI 程序我们根据到自定义时间曲线。

import SwiftUI
struct ContentView: View {
   @State private var move = false
   
   var body: some View {
      VStack{
         Circle()
            .stroke(.red, lineWidth: 6)
            .frame(width: 160)
            .offset(x : move ? 160 : -130)
            .animation(.timingCurve(0.67, -0.54, 0.28, 1.34, duration: 2), value: move)
         Button("Click"){
            move.toggle()
         }.font(.title2)
      }
   }
}
#Preview {
   ContentView()
}

输出

动画