在 SwiftUI 中,.scaleEffect
是一个修饰符(Modifier),用于 对视图进行缩放变换。它可以按比例放大或缩小视图,甚至支持在 X 轴和 Y 轴上非均匀缩放。以下是它的详细解析和实际应用指南:
1. 基本语法
均匀缩放(等比例)
swift
.scaleEffect(_ scale: CGFloat) // 统一缩放比例
- 参数 :
scale: 1.0
表示原始大小,0.5
缩小一半,2.0
放大两倍。
非均匀缩放(独立控制 X/Y 轴)
swift
.scaleEffect(x: CGFloat, y: CGFloat) // 分别控制 X 轴和 Y 轴
- 参数 :
x
: 水平方向缩放比例(如1.5
横向拉宽)。y
: 垂直方向缩放比例(如0.8
纵向压扁)。
锚点控制(以特定点为中心缩放)
swift
.scaleEffect(_ scale: CGFloat, anchor: UnitPoint) // 指定锚点
- 锚点 :
- 默认为
UnitPoint.center
(中心点)。 - 其他选项:
.topLeading
、.bottomTrailing
等(完整锚点列表)。
- 默认为
2. 核心功能
(1)基础缩放
swift
Text("Hello")
.scaleEffect(1.5) // 放大 1.5 倍
效果 :
视图从中心点等比放大。
(2)动态交互缩放
swift
@State private var isScaled = false
Button("点击缩放") {
withAnimation(.spring()) {
isScaled.toggle()
}
}
.scaleEffect(isScaled ? 1.2 : 1.0) // 点击时放大 20%
(3)非均匀变形
swift
Image("Cat")
.resizable()
.scaleEffect(x: 1.3, y: 0.7) // 横向拉宽,纵向压扁
效果 :
类似"胖猫"效果。
3. 实际应用场景
场景 1:按钮点击反馈
swift
Button("提交") {
// 提交逻辑
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.scaleEffect(isPressed ? 0.95 : 1.0) // 点击时轻微缩小
.animation(.easeOut(duration: 0.1), value: isPressed)
场景 2:视图入场动画
swift
struct ContentView: View {
@State private var isVisible = false
var body: some View {
VStack {
if isVisible {
Text("Welcome!")
.scaleEffect(isVisible ? 1.0 : 0.1) // 从 10% 缩放到原始大小
.animation(.spring(), value: isVisible)
}
Button("显示/隐藏") {
isVisible.toggle()
}
}
}
}
场景 3:镜像翻转效果
swift
Image("Logo")
.scaleEffect(x: -1.0, y: 1.0) // 水平翻转(X 轴取反)
4. 与其他修饰符的关系
修饰符 | 作用 | 与 .scaleEffect 的区别 |
---|---|---|
.frame() |
设置固定尺寸 | 直接约束视图大小,不改变内容比例 |
.aspectRatio() |
调整宽高比 | 仅限制比例,不缩放内容 |
.transformEffect() |
通用矩阵变换 | 可实现更复杂的变形(如旋转+缩放) |
5. 注意事项
-
性能优化
- 对复杂视图(如嵌套
VStack
)缩放时,建议用.drawingGroup()
提升渲染性能。 - 避免在滚动视图(
List
/ScrollView
)中频繁缩放动态内容。
- 对复杂视图(如嵌套
-
布局影响
- 缩放后的视图仍会占用布局的原始空间(需配合
.clipped()
裁剪溢出部分)。
- 缩放后的视图仍会占用布局的原始空间(需配合
-
动画组合
-
与
.rotationEffect
、.offset
结合可实现更丰富的动画效果:swiftText("✨") .scaleEffect(scale) .rotationEffect(.degrees(angle)) .animation(.easeInOut, value: scale)
-
6. 完整代码示例
动态缩放 + 锚点控制
swift
struct ScaleExample: View {
@State private var scale: CGFloat = 1.0
@State private var anchor = UnitPoint.center
var body: some View {
VStack {
Text("缩放锚点实验")
.padding()
.background(Color.orange)
.scaleEffect(scale, anchor: anchor) // 动态锚点
.animation(.spring(), value: scale)
Slider(value: $scale, in: 0.1...2.0, label: { Text("缩放比例") })
Picker("锚点", selection: $anchor) {
Text("左上").tag(UnitPoint.topLeading)
Text("中心").tag(UnitPoint.center)
Text("右下").tag(UnitPoint.bottomTrailing)
}
.pickerStyle(.segmented)
}
.padding()
}
}
总结
功能 | 代码示例 |
---|---|
等比缩放 | .scaleEffect(0.8) |
非均匀缩放 | .scaleEffect(x: 1.2, y: 0.8) |
锚点控制 | .scaleEffect(1.5, anchor: .topLeading) |
交互动画 | .scaleEffect(isActive ? 1.1 : 1.0).animation(.spring()) |
核心用途 :
✅ 实现点击反馈、入场动画等交互效果
✅ 创建视觉变形(如镜像翻转、压扁拉伸)
✅ 精细控制视图的呈现比例
掌握 .scaleEffect
能让你的界面动态表现力大幅提升! 🎨