iOS 16 WidgetKit 上的动画

huangapple go评论100阅读模式
英文:

Animations on iOS16 WidgetKit

问题

我想创建一个iOS时钟小组件,其中秒针以跳跃式动画的方式移动,动画效果如下图所示。秒针每秒钟都会弹跳。

我知道_ClockHandRotationEffect可以实现秒针旋转动画,但该界面的动画是连续旋转的,秒针会持续移动,而不是下面视频中的跳秒动画。

如何在WidgetKit中实现跳跃式动画

跳跃式动画

iOS 16 WidgetKit 上的动画

连续旋转动画:

iOS 16 WidgetKit 上的动画

英文:

I want to create a iOS Clock Widget where seconds move in a jumping motion, and the animation effect is shown in the following image. The second hand bouncing every second.

I know _ClockHandRotationEffect can achieve second rotation animation, but the animation of this interface is Continuous rotation, the second hand will continue to move, not the jump second animation in the following video.

How to implement jumping motion animations in the WidgetKit?

Jumping motion animation:

iOS 16 WidgetKit 上的动画

Continuous rotation animation:

iOS 16 WidgetKit 上的动画

答案1

得分: 1

经过长时间的研究,我终于找到了解决方法。

1. 每秒一个时间轴

这种方法最容易实现,但如果一次设置大量的时间轴,比如你需要在30分钟内设置30*60=1800个时间轴,WidgetKit 将会卡住,并且小组件将经常重新加载,加载会失败,导致小组件停止。

2. 使用私有API

这种方法可以实现连续动画,但可能在App Store审核时被拒绝,而且更有可能导致应用被下架。

在研究了长时间的WidgetKit API接口后,我在Apple论坛上找到了一篇帖子,https://developer.apple.com/forums/thread/720640。

在这篇帖子中,Apple的工作人员提到可以通过字体实现小组件动画。因此,我利用一个机会向Apple寻求了代码支持,并询问了如何通过字体配合实现小组件动画。他们没有给出具体的代码实现,只是简单地提到可以通过字体和SwiftUI Text的.timer实现动画。

1. 制作自己的字体文件

您可以使用Glyphs等工具创建ttf文件,并使用连字工具将00、01、02等两位数组合成一个字符进行显示。

https://glyphsapp.com/learn/ligatures

创建一个字体文件:

然后将其导出为ttf或otf文件,并将其导入Xcode项目。

2. 在小组件中使用Text计时器并设置自定义字体

struct widgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack() {
            Text(entry.date, style: .time)
            Text(Calendar.current.startOfDay(for: Date()), style: .timer)
                .multilineTextAlignment(.center)
            Text(Calendar.current.startOfDay(for: Date()), style: .timer)
                .font(Font.custom("test-font-Regular", size: 30))
                .multilineTextAlignment(.center)
        }
    }
}

这是一个简单的示例,我们可以制作更复杂的字体文件以实现各种复杂的动画。

我发布了一个GitHub项目,其中包含测试字体文件和代码。
https://github.com/liudhzhyym/WidgetAnimationSample

英文:

After a long research, I finally found the solution.

<img src="https://i.stack.imgur.com/s9T4a.gif" width="400" />

As we all know, it is very difficult to implement widget animation in WidgetKit, and almost all animation APIs are not available in WidgetKit.

There are probably several ways to implement WidgetKit:

1. One timelime per second

This method is the easiest to implement, but if you set a large number of timelines at one time, for example, you need to set 30*60=1800 timelines in 30 minutes, WidgetKit will be stuck, and the widget will be reloaded frequently, and the loading will fail, causing the widget to stop.

2. Using private API

This method can achieve continuous animation, but it may be rejected during appstore review, and it is more likely to cause the app to be removed from the shelf.

After studying the API interface of WidgetKit for a long time, I found a post on the Apple forum, https://developer.apple.com/forums/thread/720640 .

In this post, the Apple staff mentioned that widget animation can be realized with fonts. For this reason, I used an opportunity to seek code support from Apple and asked how to realize widget animation through font coordination. They did not give specific code implementation, just simple mentioned that animation can be realized through fonts and swiftui Text .timer.

1. Make a font file yourself

You can use tools such as Glyphs to create a ttf file, and use the ligature tool to combine two-digit combinations such as 00, 01, 02...59 into one character for display.

https://glyphsapp.com/learn/ligatures

Create a font file:

<img src="https://github.com/liudhzhyym/WidgetAnimationSample/blob/master/preview/font.jpg" alt="preview" width="800"/>

Then export it as ttf or otf file, import it to Xcode project.

2. Use Text timer in Widget and set custom font

struct widgetEntryView : View {
     var entry: Provider.Entry

     var body: some View {
         VStack() {
             Text(entry.date, style: .time)
             Text(Calendar. current. startOfDay(for: Date()), style: .timer)
                 .multilineTextAlignment(.center)
             Text(Calendar. current. startOfDay(for: Date()), style: .timer)
                 .font(Font.custom(&quot;test-font-Regular&quot;, size: 30))
                 .multilineTextAlignment(.center)
         }
     }
}

This is a simple example, we can make more complex font files to achieve various complex animations.

I released a github project, which contains test font files and codes.
https://github.com/liudhzhyym/WidgetAnimationSample

huangapple
  • 本文由 发表于 2023年6月29日 11:48:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577949.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定