优化:刷新率自适应省电 + 删除空桥接头
- 刷新率自适应: * 翻页动画进行中保持 60fps 保证流畅;静止时自动降频 * 显示秒时空闲降到 0.1s(10fps,跨秒检测延迟≤0.1s 不可见) * 关闭秒显示后空闲降到 1.0s 进一步省电 * 静止且无变化时跳过整屏重绘(setNeedsDisplay),仅保留低频轮询 - 删除空的 FlipClockSaver-Bridging-Header.h,并移除 pbxproj 中 SWIFT_OBJC_BRIDGING_HEADER 与 membershipExceptions 相关引用 (项目无 Obj-C 代码,桥接头多余) - Release 构建 BUILD SUCCEEDED,Developer ID 正式签名 + 验证通过
This commit is contained in:
@@ -10,22 +10,9 @@
|
|||||||
7B3DB23F3022DC2F00B3B568 /* FlipClockSaver.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlipClockSaver.saver; sourceTree = BUILT_PRODUCTS_DIR; };
|
7B3DB23F3022DC2F00B3B568 /* FlipClockSaver.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlipClockSaver.saver; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
|
||||||
7B3DB24E3022DC6000B3B568 /* Exceptions for "FlipClockSaver" folder in "FlipClockSaver" target */ = {
|
|
||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
|
||||||
membershipExceptions = (
|
|
||||||
"FlipClockSaver-Bridging-Header.h",
|
|
||||||
);
|
|
||||||
target = 7B3DB23E3022DC2F00B3B568 /* FlipClockSaver */;
|
|
||||||
};
|
|
||||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
7B3DB2413022DC2F00B3B568 /* FlipClockSaver */ = {
|
7B3DB2413022DC2F00B3B568 /* FlipClockSaver */ = {
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
exceptions = (
|
|
||||||
7B3DB24E3022DC6000B3B568 /* Exceptions for "FlipClockSaver" folder in "FlipClockSaver" target */,
|
|
||||||
);
|
|
||||||
path = FlipClockSaver;
|
path = FlipClockSaver;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@@ -275,7 +262,6 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "FlipClockSaver/FlipClockSaver-Bridging-Header.h";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 6.0;
|
SWIFT_VERSION = 6.0;
|
||||||
WRAPPER_EXTENSION = saver;
|
WRAPPER_EXTENSION = saver;
|
||||||
@@ -303,7 +289,6 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "FlipClockSaver/FlipClockSaver-Bridging-Header.h";
|
|
||||||
SWIFT_VERSION = 6.0;
|
SWIFT_VERSION = 6.0;
|
||||||
WRAPPER_EXTENSION = saver;
|
WRAPPER_EXTENSION = saver;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
//
|
|
||||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
|
||||||
//
|
|
||||||
|
|
||||||
@@ -126,23 +126,41 @@ final class FlipClockSaverView: ScreenSaverView {
|
|||||||
refreshInfo()
|
refreshInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
override var animationTimeInterval: TimeInterval {
|
// 刷新率自适应:翻页动画进行中用 60fps 保证流畅;静止时自动降频省电。
|
||||||
get { 1.0 / 60 }
|
// 显示秒时仍需逐秒检测是否跨秒,空闲降到 0.1s(10fps,检测延迟≤0.1s 不可见);
|
||||||
set {}
|
// 关闭秒显示后只在整分翻动,空闲可降到 1.0s 进一步省电。
|
||||||
}
|
private static let animFrameInterval: TimeInterval = 1.0 / 60.0
|
||||||
|
private static let idleFrameInterval: TimeInterval = 0.1
|
||||||
|
private static let idleNoSecondsFrameInterval: TimeInterval = 1.0
|
||||||
|
|
||||||
override func animateOneFrame() {
|
override func animateOneFrame() {
|
||||||
let now = CACurrentMediaTime()
|
let now = CACurrentMediaTime()
|
||||||
frameTime = now
|
frameTime = now
|
||||||
let comps = Calendar.current.dateComponents([.hour, .minute, .second], from: Date())
|
let comps = Calendar.current.dateComponents([.hour, .minute, .second], from: Date())
|
||||||
let key = (comps.hour ?? 0) * 3600 + (comps.minute ?? 0) * 60 + (comps.second ?? 0)
|
let key = (comps.hour ?? 0) * 3600 + (comps.minute ?? 0) * 60 + (comps.second ?? 0)
|
||||||
if key != lastKey {
|
let keyChanged = key != lastKey
|
||||||
|
if keyChanged {
|
||||||
lastKey = key
|
lastKey = key
|
||||||
update(animated: true, at: now)
|
update(animated: true, at: now)
|
||||||
}
|
}
|
||||||
|
let wasAnimating = digits.contains { $0.isAnimating }
|
||||||
for d in digits { d.advance(to: now) }
|
for d in digits { d.advance(to: now) }
|
||||||
|
let isAnimating = digits.contains { $0.isAnimating }
|
||||||
|
let justFinished = wasAnimating && !isAnimating
|
||||||
syncSettingsIfNeeded(now: now)
|
syncSettingsIfNeeded(now: now)
|
||||||
setNeedsDisplay(bounds)
|
|
||||||
|
// 自适应刷新率:动画进行中保持 60fps;静止时降到低频省电
|
||||||
|
let desired = isAnimating
|
||||||
|
? Self.animFrameInterval
|
||||||
|
: (showSeconds ? Self.idleFrameInterval : Self.idleNoSecondsFrameInterval)
|
||||||
|
if abs(animationTimeInterval - desired) > 0.0001 {
|
||||||
|
animationTimeInterval = desired
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅在“跨秒 / 动画中 / 动画刚结束”时才重绘,彻底静止时不触发整屏重绘
|
||||||
|
if keyChanged || isAnimating || justFinished {
|
||||||
|
setNeedsDisplay(bounds)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 轮询兜底:即使通知未送达(如跨进程/模块缓存),也能在约 0.5 秒内同步设置
|
// 轮询兜底:即使通知未送达(如跨进程/模块缓存),也能在约 0.5 秒内同步设置
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ final class FlipDigit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 是否正处于翻页动画中(供视图判断是否需要高刷新率)
|
||||||
|
var isAnimating: Bool { animating }
|
||||||
|
|
||||||
func draw(in ctx: CGContext,
|
func draw(in ctx: CGContext,
|
||||||
rect: CGRect,
|
rect: CGRect,
|
||||||
radius: CGFloat,
|
radius: CGFloat,
|
||||||
|
|||||||
Reference in New Issue
Block a user