致谢: @alonsoholmes 为此解决方案贡献了大部分代码。
在 iOS 13.5 中,SwiftUI 的 rotationEffect
修饰符在动画旋转变化时会“绕远路”。例如,从 350° 旋转到 20° 将覆盖 330° 的旋转,即使这些角度仅相差 30°。
UIKit 的动画库可以正确处理这种情况。这个 Swift 包是一个简单的封装,可以通过修饰符访问,可以将 UIKit 旋转行为添加到您的 SwiftUI 视图中。
UIRotationEffect 支持 Swift Package Manager。只需在 *XCode > File > Swift Packages > Add Package Dependency* 中添加此 url。
https://github.com/DominicHolmes/UIRotationEffect
将 UIRotationEffect
导入到您的项目中。 然后在通常使用 .rotationEffect(angle)
的任何地方使用 .uiRotationEffect(angle)
。
因为动画现在由 UIKit 处理,如果您想自定义它,您必须传入额外的选项。uiRotationEffect
采用与 此方法 相同的所有选项。
完整的方法签名是
func uiRotationEffect(
_ angle: Angle,
duration: TimeInterval? = nil,
delay: TimeInterval? = nil,
options: UIView.AnimationOptions? = nil,
completion: ((Bool) -> Void)? = nil
) -> some View
使用示例
VStack {
Text("UIRotation Effect")
.font(.caption)
Image(systemName: "arrow.up")
.font(.largeTitle)
.foregroundColor(.primary)
.padding()
.border(Color.blue)
.uiRotationEffect(angle)
.frame(width: 60, height: 60)
Text("UIRotationEffect with options")
.font(.caption)
Image(systemName: "arrow.up")
.font(.largeTitle)
.foregroundColor(.primary)
.padding()
.border(Color.blue)
.uiRotationEffect(angle, duration: 2.0, options: [.curveEaseInOut])
.frame(width: 60, height: 60)
}