Animation — rotationEffect
This article is extracted from the chat log with AI. Please identify it with caution.

在 SwiftUI 中,rotationEffect 是一个用于对视图进行二维旋转变换的修饰符。它允许你通过指定旋转角度和锚点(旋转中心)来调整视图的方向。以下是它的使用方式和关键点:


基本用法 #

  1. 通过角度旋转
    使用 Angle 类型指定旋转角度,支持度数(.degrees)或弧度(.radians):

    Text("Hello, SwiftUI")
        .rotationEffect(Angle.degrees(45)) // 旋转45度
    
    Text("Hello, SwiftUI")
        .rotationEffect(Angle.radians(.pi / 4)) // 旋转π/4弧度(等价于45度)
    
  2. 指定旋转锚点
    默认锚点为视图中心(.center),但可自定义其他位置(如 .topLeading.bottomTrailing 等):

    Text("Hello, SwiftUI")
        .rotationEffect(.degrees(30), anchor: .topLeading) // 以左上角为轴旋转30度
    

动态旋转与动画 #

结合 @State 和动画修饰符,实现交互式旋转效果:

@State private var angle: Double = 0

var body: some View {
    VStack {
        Text("Rotate Me")
            .rotationEffect(.degrees(angle))
            .animation(.easeInOut, value: angle) // 添加平滑动画

        Slider(value: $angle, in: 0...360) // 滑动条控制角度
        Button("旋转90度") { angle += 90 } // 点击按钮增加角度
    }
}

注意事项 #

  1. 布局影响
    旋转后的视图仍占据原始布局空间,可能导致与其他视图重叠。若需布局跟随旋转调整,可结合 fixedSize() 或布局容器(如 ZStack)处理。

  2. 变换顺序
    修饰符的应用顺序会影响最终效果(例如先旋转再缩放 vs 先缩放再旋转)。

  3. 裁剪问题
    旋转可能导致视图超出父视图范围,可用 .clipped() 裁剪超出部分:

    Text("Hello")
        .rotationEffect(.degrees(45))
        .clipped() // 裁剪超出区域
    

示例代码 #

struct RotationExample: View {
    @State private var angle: Double = 0

    var body: some View {
        VStack {
            Text("🚀 SwiftUI")
                .font(.largeTitle)
                .padding()
                .background(Color.orange)
                .rotationEffect(.degrees(angle), anchor: .bottom)
                .animation(.spring(dampingFraction: 0.5), value: angle)

            Button("旋转!") { angle += 45 }
        }
    }
}

总结 #

  • 核心参数:旋转角度(Angle)和锚点(anchor)。
  • 动态控制:结合 @State 和动画实现交互效果。
  • 布局处理:注意旋转对布局的影响,必要时调整视图层次或使用修饰符。

通过 rotationEffect,你可以轻松为视图添加旋转效果,增强用户界面的动态表现力。

完整参数分类 #

好的!以下是 SwiftUI 中 rotationEffect完整参数分类和详细介绍,包括所有可能的用法和参数细节。


一、rotationEffect 的两种主要形式 #

rotationEffect 有两个重载版本,分别接受不同的参数:

1. 基于 Angleanchor 的旋转 #

func rotationEffect(
    _ angle: Angle,          // 旋转角度
    anchor: UnitPoint = .center // 旋转锚点(默认中心)
) -> some View

2. 基于 CGAffineTransform 的旋转(高级用法) #

func rotationEffect(
    _ transform: CGAffineTransform // 仿射变换矩阵
) -> some View

二、参数详解 #

1. angle: Angle(旋转角度) #

  • 作用:定义视图绕锚点旋转的角度。

  • 类型Angle,支持以下初始化方法:

    • 度数.degrees(Double)
      Angle.degrees(45) // 旋转45度
      
    • 弧度.radians(Double)
      Angle.radians(.pi / 4) // 旋转π/4弧度(等价于45度)
      
  • 动态控制:通常结合 @State@Binding 实现动态旋转:

    @State private var angle: Double = 0
    Text("Hello").rotationEffect(.degrees(angle))
    

2. anchor: UnitPoint(旋转锚点) #

  • 作用:定义旋转的中心点。

  • 类型UnitPoint,取值范围为视图的相对坐标(从 (0,0)(1,1))。

  • 默认值.center(视图中心)。

  • 预定义锚点

    位置
    .center中心
    .topLeading左上角
    .top顶部中点
    .topTrailing右上角
    .leading左侧中点
    .trailing右侧中点
    .bottomLeading左下角
    .bottom底部中点
    .bottomTrailing右下角
  • 自定义锚点

    // 使用相对坐标定义锚点
    Text("Hello")
      .rotationEffect(.degrees(30), anchor: UnitPoint(x: 0.2, y: 0.8))
    

3. transform: CGAffineTransform(仿射变换) #

  • 作用:直接通过仿射变换矩阵定义旋转(适合复杂变换或与其他变换组合)。
  • 类型CGAffineTransform
  • 示例
    // 旋转45度(等效于第一种形式)
    Text("Hello")
      .rotationEffect(CGAffineTransform(rotationAngle: CGFloat(Angle.degrees(45).radians)))
    
    // 组合旋转和缩放
    Text("Hello")
      .rotationEffect(
        CGAffineTransform(rotationAngle: .pi/4)
          .scaledBy(x: 1.5, y: 1.5)
      )
    

三、高级用法与注意事项 #

1. 动画与过渡 #

  • 隐式动画

    Text("Hello")
      .rotationEffect(.degrees(angle))
      .animation(.easeInOut(duration: 1), value: angle)
    
  • 显式动画

    Button("旋转") {
      withAnimation(.spring()) {
        angle += 90
      }
    }
    

2. 变换顺序的影响 #

修饰符的顺序会影响最终效果:

  • 先旋转后偏移

    Text("Hello")
      .rotationEffect(.degrees(45))
      .offset(x: 50) // 偏移旋转后的视图
    
  • 先偏移后旋转

    Text("Hello")
      .offset(x: 50) // 先偏移原始视图
      .rotationEffect(.degrees(45)) // 旋转偏移后的视图
    

3. 布局与裁剪 #

  • 布局空间:旋转后的视图仍占据原始布局空间。若需布局跟随旋转后的尺寸调整,使用 fixedSize()

    Text("Hello")
      .rotationEffect(.degrees(45))
      .fixedSize() // 强制使用实际渲染后的尺寸
    
  • 裁剪超出部分

    Text("Hello")
      .rotationEffect(.degrees(45))
      .clipped() // 裁剪超出父视图的部分
    

4. 三维旋转的限制 #

  • rotationEffect 仅支持二维旋转。若需三维旋转,需使用 rotation3DEffect
    Text("Hello")
      .rotation3DEffect(
        .degrees(angle),
        axis: (x: 1, y: 0, z: 0) // 绕X轴旋转
      )
    

四、完整示例代码 #

示例 1:动态锚点与动画 #

struct RotationDemo: View {
    @State private var angle: Double = 0
    @State private var anchor: UnitPoint = .center

    var body: some View {
        VStack {
            Text("SwiftUI")
                .font(.title)
                .padding()
                .background(Color.blue.opacity(0.3))
                .rotationEffect(.degrees(angle), anchor: anchor)
                .animation(.easeInOut(duration: 1), value: angle)
                .animation(.easeInOut(duration: 1), value: anchor)

            Slider(value: $angle, in: 0...360)

            Picker("锚点", selection: $anchor) {
                Text("Center").tag(UnitPoint.center)
                Text("TopLeading").tag(UnitPoint.topLeading)
                Text("Custom (0.2, 0.8)").tag(UnitPoint(x: 0.2, y: 0.8))
            }
            .pickerStyle(.segmented)
        }
    }
}

示例 2:组合仿射变换 #

Text("Advanced")
    .rotationEffect(
        CGAffineTransform(rotationAngle: .pi/4)
            .translatedBy(x: 50, y: 0) // 先旋转后平移
    )

五、总结表格 #

参数/方法类型说明
angleAngle旋转角度(度数或弧度)
anchorUnitPoint旋转中心点(默认 .center
CGAffineTransformCGAffineTransform直接操作仿射变换矩阵

通过以上详细分类和示例,你可以精确控制 rotationEffect 的所有参数,实现复杂的旋转效果和动画。

本文共 1794 字,创建于 Mar 15, 2025
相关标签: Xcode, SwiftUI, ByAI