前言
经常看到别人充电时会有各种动态的充电动画效果,这里探索一下自定义充电动画的实现过程,末尾附demo链接。
限制
这种充电动画需要先解锁,锁屏无法执行
实现
1.充电动画展示
先创建一个用于充电时展示的动画视图
scss 代码解读复制代码// 定义充电动画视图
struct ChargingAnimationView: View {
let onClose: () -> Void
@State private var scale: CGFloat = 1.0
@State private var opacity: Double = 0.5
var body: some View {
ZStack {
// 背景
Color.black.edgesIgnoringSafeArea(.all)
// 电池动画
VStack {
Image(systemName: "battery.100.bolt")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.foregroundColor(.green)
.scaleEffect(scale)
.opacity(opacity)
Text("充电中...")
.foregroundColor(.white)
.font(.title)
.opacity(opacity)
}
}
.onTapGesture {
// 关闭window
onClose()
}
.onAppear {
// 创建循环动画
withAnimation(Animation.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) {
scale = 1.2
opacity = 1.0
}
}
}
}
创建一个窗口管理器用于在window层展示充电动画视图
swift 代码解读复制代码// 用于管理窗口的单例类
class WindowManager: ObservableObject {
static let shared = WindowManager()
private var additionalWindow: UIWindow?
@Published var isWindowVisible = false
func showWindow() {
guard additionalWindow == nil else { return }
// 获取当前 key window 的场景,会出现获取的activationState是非激活状态,这里暂时先不做处理
guard let windowScene = UIApplication.shared.connectedScenes
// .filter({ $0.activationState == .foregroundInactive })
.first as? UIWindowScene else {
return
}
let window = UIWindow(windowScene: windowScene)
// 创建承载 SwiftUI 视图的控制器
let contentView = ChargingAnimationView {
self.hideWindow()
}
let hostingController = UIHostingController(rootView: contentView)
window.rootViewController = hostingController
// window.backgroundColor = .black // 确保窗口有背景色
// window.windowLevel = .alert + 1 // 设置较高的窗口层级
window.frame = windowScene.coordinateSpace.bounds
// 使窗口可见
window.makeKeyAndVisible()
window.isHidden = false
self.additionalWindow = window
self.isWindowVisible = true
}
func hideWindow() {
additionalWindow?.isHidden = true
additionalWindow = nil
isWindowVisible = false
}
}
定义好后测试一下动画效果
scss 代码解读复制代码struct ContentView: View {
@StateObject private var windowManager = WindowManager.shared
var body: some View {
VStack {
Text("主窗口")
.font(.title)
Button("打开新窗口") {
windowManager.showWindow()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
2.注册快捷指令
swift 代码解读复制代码import AppIntents
import SwiftUI
struct ChargingShortcut: AppIntent {
static var title = LocalizedStringResource("充电动画")
static var description = IntentDescription("充电时显示动画")
// 意图执行时,是否自动将应用拉起到前台
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some IntentResult {
// 打开充电动画效果
WindowManager.shared.showWindow()
return .result()
}
}
注册完成在快捷指令中新建快捷指令搜索【充电动画】添加即可看到快捷指令效果
3.快捷指令自动化
在快捷指令App中点击【自动化】->【充电器】->【已连接】->【添加操作】->搜索【充电动画】->取消【运行前询问】
项目链接
代码放到了github上,需要的自取
快捷指令口令
见原文:【iOS小组件实战】自定义充电动画)
本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。
评论记录:
回复评论: