UIRotationEffect

致谢: @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)

}

已知问题(欢迎提供想法)