为你的 App 带来令人愉悦的 SwiftUI 效果。
要将软件包依赖项添加到你的 Xcode 项目中,请选择File > Add Package,然后输入此存储库的 URL (https://github.com/EmergeTools/Pow)。
要将软件包依赖项添加到 Swift Package,请将此存储库添加到你的依赖项列表中。
.package(url: "https://github.com/EmergeTools/Pow", from: Version(1, 0, 0))
并将它作为 product 添加到你的 target 中
.product(name: "Pow", package: "Pow")
如果你要从之前闭源的 Pow 框架迁移到新的开源包,请参考我们的迁移指南。如果遇到任何问题,请提交 issue。
Pow 包含精选的 SwiftUI 转场动画以及每次值更新时触发的变化效果。
你可以在 Pow 网站上找到所有效果的预览。如果你有 iOS 开发者环境,可以查看 Pow 示例 App。
此项目提供了多种向维护者提供反馈的形式。
如果你正在研究如何使用 Pow 或其某个效果,我们建议你首先查阅效果示例页面。
如果你仍然有疑问、改进建议或改进 Pow 的方法,此项目利用 GitHub 的 Issues 来管理你的请求。如果你发现错误并希望报告它,我们将非常感谢你提交 issue。
变化效果是指每次值发生变化时都会触发视觉或触觉效果的效果。
使用 changeEffect
修饰符,并传入 AnyChangeEffect
以及要监视更改的值。
Button {
post.toggleLike()
} label: {
Label(post.likes.formatted(), systemName: "heart.fill")
}
.changeEffect(.spray { heart }, value: post.likes, isEnabled: post.isLiked)
.tint(post.isLiked ? .red : .gray)
你可以从以下变化效果中进行选择:Spray、Haptic Feedback、Jump、Ping、Rise、Shake、Shine 和 Spin。
一种从原点向上发射不同阴影和大小的多个粒子的效果。
likeButton
.changeEffect(
.spray(origin: .center) { Image(systemName: "heart.fill") },
value: likes
)
origin
:粒子的原点。layer
:用于渲染效果的 ParticleLayer
,默认为 local
。particles
:要发射的粒子。static func spray(origin: UnitPoint = .center, layer: ParticleLayer = .local, @ViewBuilder _ particles: () -> some View) -> AnyChangeEffect
每当值发生变化时,触发触觉反馈以传达成功、失败和警告。
notification
:要触发的反馈类型。static func feedback(hapticNotification type: UINotificationFeedbackGenerator.FeedbackType) -> AnyChangeEffect
每当值发生变化时,触发触觉反馈以模拟物理冲击。
impact
:要触发的反馈样式。static func feedback(hapticImpact style: UIImpactFeedbackGenerator.FeedbackStyle) -> AnyChangeEffect
每当值发生变化时,触发触觉反馈以指示选择的变化。
static var feedbackHapticSelection: AnyChangeEffect
使视图跳跃给定的高度,然后弹跳几次才稳定下来。
height
:跳跃的高度。static func jump(height: CGFloat) -> AnyChangeEffect
在视图后面添加一个或多个缓慢增长和淡出的形状。
该形状将由当前的色调样式着色。
shape
:用于效果的形状。count
:要发射的形状数量。 static func ping(shape: some InsettableShape, count: Int) -> AnyChangeEffect
一种在视图后面添加一个或多个缓慢增长和淡出的形状的效果。
shape
:用于效果的形状。style
:用于效果的样式。count
:要发射的形状数量。static func ping(shape: some InsettableShape, style: some ShapeStyle, count: Int) -> AnyChangeEffect
一种从原点发射提供的粒子,并在左右移动的同时缓慢向上漂浮的效果。
origin
:粒子的原点。layer
:用于渲染效果的 ParticleLayer
,默认为 local
。particles
:要发射的粒子。static func rise(origin: UnitPoint = .center, layer: ParticleLayer = .local, @ViewBuilder _ particles: () -> some View) -> AnyChangeEffect
当发生变化时,摇动视图。
static var shake: AnyChangeEffect
一种当发生变化时摇动视图的效果。
rate
:摇动的速率。static func shake(rate: ShakeRate) -> AnyChangeEffect
用在视图上移动的光泽突出显示视图。
光泽从顶部前沿移动到底部后沿。
static var shine: AnyChangeEffect
用在视图上移动的光泽突出显示视图。
光泽从顶部前沿移动到底部后沿。
static func shine(duration: Double) -> AnyChangeEffect
用在视图上移动的光泽突出显示视图。
角度相对于当前的 layoutDirection
,因此 0° 表示向后沿扫描,90° 表示向底部边缘扫描。
angle
:动画的角度。duration
:动画的持续时间。static func shine(angle: Angle, duration: Double = 1.0) -> AnyChangeEffect
每当值发生变化时,触发声音效果作为反馈。
此效果不会中断或降低当前正在播放的任何其他音频。不能保证此效果会被触发;效果的运行取决于用户的静音开关位置和当前的播放设备。
为了向用户传递重要信息,你应该始终将音频效果与视觉提示结合使用。
soundEffect
:要触发的声音效果。static func feedback(_ soundEffect: SoundEffect) -> AnyChangeEffect
当发生变化时,围绕给定轴旋转视图。
static var spin: AnyChangeEffect
当发生变化时,围绕给定轴旋转视图。
static func spin(axis: (x: CGFloat, y: CGFloat, z: CGFloat), anchor: UnitPoint = .center, anchorZ: CGFloat = 0, perspective: CGFloat = 1 / 6) -> AnyChangeEffect
每个变化效果都可以延迟,以便在一段时间后触发效果。
Button("Submit") {
<#code#>
}
.buttonStyle(.borderedProminent)
.disabled(name.isEmpty)
.changeEffect(.shine.delay(1), value: name.isEmpty, isEnabled: !name.isEmpty)
delay
:以秒为单位的延迟。func delay(_ delay: Double) -> AnyChangeEffect
粒子图层是粒子效果绘制其粒子的上下文。
particleLayer(name:)
视图修饰符将视图包装在具有给定名称的粒子图层中。
粒子效果(如 AnyChangeEffect.spray
)可以在视图树中的此位置渲染其粒子,以避免被其直接祖先裁剪。
例如,某些 List
样式可能会裁剪其行。使用 particleLayer(_:)
在整个 List
甚至其封闭的 NavigationStack
上方渲染粒子。
func particleLayer(name: AnyHashable) -> some View
所有转场动画都在 movingParts
静态变量下命名空间,例如:
myView.transition(.movingParts.anvil)
一种从顶部向下掉落视图并带有匹配的触觉反馈的转场动画。
该转场动画仅在插入时执行,需要 1.4 秒。
static var anvil: AnyTransition
一种以百叶窗的形式显示视图的转场动画。
static var blinds: AnyTransition
一种以百叶窗的形式显示视图的转场动画。
参数
slatWidth
:每个板条的宽度。style
:百叶窗的样式,可以是 .venetian
或 .vertical
。isStaggered
:所有板条是同时打开还是按顺序打开。static func blinds(slatWidth: CGFloat, style: BlindsStyle = .venetian, isStaggered: Bool = false) -> AnyTransition
一种在插入时从模糊到清晰,在移除时从清晰到模糊的转场动画。
static var blur: AnyTransition
一种将视图向下移动的转场动画,任何超调都会导致视图的弹性变形。
static var boing: AnyTransition
一种从指定的边缘移动视图以进行插入的转场动画,
并在移除时朝向它移动,任何超调都会导致弹性的
视图的变形。
static func boing(edge: Edge) -> AnyTransition
一种使用围绕视图中心点的顺时针扫描的转场动画。
static var clock: AnyTransition
一种使用围绕视图中心点的顺时针扫描的转场动画。
blurRadius
:应用于蒙版的模糊半径。static func clock(blurRadius: CGFloat) -> AnyTransition
一种在稳定之前多次切换视图可见性的转场动画。
static var flicker: AnyTransition
一种在稳定之前多次切换视图可见性的转场动画。
count
:切换可见性的次数。static func flicker(count: Int) -> AnyTransition
一种在插入时从完全黑暗到完全可见,在移除时从完全可见到完全黑暗的转场动画。
static var filmExposure: AnyTransition
一种通过将视图旋转朝向查看者来插入,并通过将视图旋转远离查看者来移除的转场动画。
注意:动画的任何超调都会导致视图继续旋转超过视图的正常状态,然后最终稳定下来。
static var flip: AnyTransition
一种通过将对角线擦拭与白色条纹结合来显示视图的转场动画。
static var glare: AnyTransition
一种通过将擦拭与彩色条纹结合来显示视图的转场动画。
角度相对于当前的 layoutDirection
,因此 0° 表示在插入时向后沿扫描,90° 表示向底部边缘扫描。
在此示例中,视图的移除使用具有指数缓入曲线的光晕,并结合预期的缩放动画,从而实现更具戏剧性的退出。
infoBox
.transition(
.asymmetric(
insertion: .movingParts.glare(angle: .degrees(225)),
removal: .movingParts.glare(angle: .degrees(45)
)
.animation(.movingParts.easeInExponential(duration: 0.9))
.combined(with:
.scale(scale: 1.4)
.animation(.movingParts.anticipate(duration: 0.9).delay(0.1)
)
)
)
)
direction
:擦拭的角度。color
:光晕效果的颜色。static func glare(angle: Angle, color: Color = .white) -> AnyTransition
一种在插入时呈现为增长的圆形,在移除时呈现为收缩的圆形的转场动画。
origin
:圆形增长或收缩的中心点。blurRadius
:应用于蒙版的模糊半径。static func iris(origin: UnitPoint = .center, blurRadius: CGFloat = 0) -> AnyTransition
一种从插入时视图的指定边缘移动视图,并在移除时朝向它的转场动画。
static func move(edge: Edge) -> AnyTransition
一种以指定的角度移动视图的转场动画。
角度相对于当前的 layoutDirection
,因此 0° 表示在插入时向后沿动画,90° 表示向底部边缘插入。
在此示例中,视图插入通过将其移动到顶部后沿角来动画,而移除通过将其移动到底部边缘来动画。
Text("Hello")
.transition(
.asymmetric(
insertion: .movingParts.move(angle: .degrees(45)),
removal: .movingParts.move(angle: .degrees(90))
)
)
angle
:动画的方向。static func move(angle: Angle) -> AnyTransition
一种显示具有涟漪效果和大量彩色粒子的视图的转场动画。
该转场动画仅在插入时执行,需要 1.2 秒。
static var pop: AnyTransition
一种显示具有涟漪效果和大量彩色粒子的视图的转场动画。
在此示例中,星星仅在从 starred == false
过渡到 starred == true
时才使用 pop 效果
Button {
starred.toggle()
} label: {
if starred {
Image(systemName: "star.fill")
.foregroundStyle(.orange)
.transition(.movingParts.pop(.orange))
} else {
Image(systemName: "star")
.foregroundStyle(.gray)
.transition(.identity)
}
}
该转场动画仅在插入时执行。
style
:用于效果的样式。static func pop<S: ShapeStyle>(_ style: S) -> AnyTransition
一种以溶解的卡通风格云移除视图的转场动画。
该转场动画仅在移除时执行,需要 0.4 秒。
static var poof: AnyTransition
一种通过从指定的旋转进行旋转来插入,并通过在三个维度中旋转到指定的旋转来移除的转场动画。
在此示例中,视图绕其底部边缘绕 y 轴旋转 90˚,就好像它是从其背面向上升起一样
Text("Hello")
.transition(.movingParts.rotate3D(
.degrees(90),
axis: (1, 0, 0),
anchor: .bottom,
perspective: 1.0 / 6.0)
)
注意:动画的任何超调都会导致视图继续旋转超过视图的正常状态,然后最终稳定下来。
angle
:旋转视图的角度。axis
:指定旋转轴的 x、y 和 z 元素。anchor
:一个位置,默认为中心,用于定义 3D 空间中的一个点,旋转围绕该点进行锚定。anchorZ
:一个位置,默认为 0,用于定义 3D 空间中的一个点,旋转围绕该点进行锚定。perspective
:相对消失点,对于此旋转默认为 1。static func rotate3D(_ angle: Angle, axis: (x: CGFloat, y: CGFloat, z: CGFloat), anchor: UnitPoint = .center, anchorZ: CGFloat = 0, perspective: CGFloat = 1) -> AnyTransition
插入时从完全明亮过渡到完全可见,移除时从完全可见过渡到完全明亮。
static var snapshot: AnyTransition
一种过渡效果,将视图从其前缘滑入,任何过冲都会导致视图的弹性变形。
static var skid: AnyTransition
一种过渡效果,将视图从指定的边缘滑入(插入时),并向该边缘滑出(移除时),任何过冲都会导致视图的弹性变形。
direction
:过渡的方向。static func skid(direction: SkidDirection) -> AnyTransition
一种三维过渡效果,在插入时从后向前,在移除时从前向后。
static var swoosh: AnyTransition
一种将视图溶解成许多小颗粒的过渡效果。
该过渡仅在移除时执行。
注意: 如果当前的
Animation
是.default
,此过渡效果将使用持续时间为 900 毫秒的缓出 (ease-out) 动画。
static var vanish: AnyTransition
一种将视图溶解成许多小颗粒的过渡效果。
该过渡仅在移除时执行。
注意: 如果当前的
Animation
是.default
,此过渡效果将使用持续时间为 900 毫秒的缓出 (ease-out) 动画。
style
:用于颗粒的样式。static func vanish<S: ShapeStyle>(_ style: S) -> AnyTransition
一种将视图溶解成许多遵循给定形状的小颗粒的过渡效果。
该过渡仅在移除时执行。
注意: 如果当前的
Animation
是.default
,此过渡效果将使用持续时间为 900 毫秒的缓出 (ease-out) 动画。
style
:用于颗粒的样式。mask
:确定颗粒放置位置的遮罩。eoFill
:一个布尔值,指示形状是否以奇偶缠绕规则解释。static func vanish<T: ShapeStyle, S: Shape>(_ style: T, mask: S, eoFill: Bool = false) -> AnyTransition
一种使用从指定边缘开始扫描(插入时)并向其扫描(移除时)的过渡效果。
edge
:扫描开始或结束的边缘。blurRadius
:应用于蒙版的模糊半径。static func wipe(edge: Edge, blurRadius: CGFloat = 0) -> AnyTransition
一种使用指定角度的扫描的过渡效果。
角度相对于当前的 layoutDirection
,因此 0° 表示在插入时向后沿扫描,90° 表示向底部边缘扫描。
angle
:动画的角度。blurRadius
:应用于蒙版的模糊半径。static func wipe(angle: Angle, blurRadius: CGFloat = 0) -> AnyTransition