feat(UI): 添加动画效果和优化界面布局
为菜单内容和指引界面添加平滑的动画过渡效果 优化权限管理区域的布局和视觉层次 调整窗口打开/关闭时的渐变动画
This commit is contained in:
@@ -250,6 +250,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
@@ -259,6 +260,7 @@
|
|||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
ENABLE_USER_SELECTED_FILES = readonly;
|
ENABLE_USER_SELECTED_FILES = readonly;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_LSUIElement = YES;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -274,7 +276,6 @@
|
|||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
INFOPLIST_KEY_LSUIElement = YES;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@@ -283,6 +284,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
@@ -292,6 +294,7 @@
|
|||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
ENABLE_USER_SELECTED_FILES = readonly;
|
ENABLE_USER_SELECTED_FILES = readonly;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_LSUIElement = YES;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -307,7 +310,6 @@
|
|||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
INFOPLIST_KEY_LSUIElement = YES;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,12 +55,15 @@ struct MenuContent: View {
|
|||||||
// 主要操作按钮:切换功能
|
// 主要操作按钮:切换功能
|
||||||
Button(action: {
|
Button(action: {
|
||||||
// 点击按钮,切换功能的开关状态
|
// 点击按钮,切换功能的开关状态
|
||||||
appState.toggleFunction()
|
withAnimation(.easeInOut(duration: 0.3)) {
|
||||||
|
appState.toggleFunction()
|
||||||
|
}
|
||||||
}) {
|
}) {
|
||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
Image(systemName: appState.isFunctionEnabled ? "stop.circle.fill" : "play.circle.fill")
|
Image(systemName: appState.isFunctionEnabled ? "stop.circle.fill" : "play.circle.fill")
|
||||||
.foregroundColor(appState.isFunctionEnabled ? .red : .green)
|
.foregroundColor(appState.isFunctionEnabled ? .red : .green)
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
|
.transition(.scale(scale: 0.8, anchor: .center))
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
Text(appState.isFunctionEnabled ? "关闭常亮" : "开启常亮")
|
Text(appState.isFunctionEnabled ? "关闭常亮" : "开启常亮")
|
||||||
.font(.body)
|
.font(.body)
|
||||||
@@ -74,11 +77,14 @@ struct MenuContent: View {
|
|||||||
.background(
|
.background(
|
||||||
RoundedRectangle(cornerRadius: 8)
|
RoundedRectangle(cornerRadius: 8)
|
||||||
.fill(appState.isFunctionEnabled ? Color.red.opacity(0.1) : Color.green.opacity(0.1))
|
.fill(appState.isFunctionEnabled ? Color.red.opacity(0.1) : Color.green.opacity(0.1))
|
||||||
|
.transition(.opacity)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
.transition(.opacity)
|
||||||
|
.animation(.easeInOut(duration: 0.3), value: appState.isFunctionEnabled)
|
||||||
|
|
||||||
// 状态显示
|
// 状态显示
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
@@ -91,6 +97,7 @@ struct MenuContent: View {
|
|||||||
Circle()
|
Circle()
|
||||||
.fill(appState.isUserIdle ? Color.orange : Color.green)
|
.fill(appState.isUserIdle ? Color.orange : Color.green)
|
||||||
.frame(width: 8, height: 8)
|
.frame(width: 8, height: 8)
|
||||||
|
.transition(.scale(scale: 0.5, anchor: .center))
|
||||||
Text(appState.isUserIdle ? "空闲" : "活动中")
|
Text(appState.isUserIdle ? "空闲" : "活动中")
|
||||||
.font(.body)
|
.font(.body)
|
||||||
|
|
||||||
@@ -112,6 +119,8 @@ struct MenuContent: View {
|
|||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
|
.transition(.opacity)
|
||||||
|
.animation(.easeInOut(duration: 0.3), value: appState.isFunctionEnabled || appState.isUserIdle)
|
||||||
}
|
}
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.background(
|
.background(
|
||||||
@@ -122,7 +131,7 @@ struct MenuContent: View {
|
|||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
// 权限管理
|
// 权限管理
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
Text("权限管理")
|
Text("权限管理")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
@@ -147,9 +156,15 @@ struct MenuContent: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.blue)
|
.foregroundColor(.blue)
|
||||||
}
|
}
|
||||||
|
.padding(8)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(Color.blue.opacity(0.05))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.padding(4)
|
|
||||||
|
|
||||||
// 打开用户与群组设置,用于管理登录项
|
// 打开用户与群组设置,用于管理登录项
|
||||||
Button(action: {
|
Button(action: {
|
||||||
@@ -164,11 +179,16 @@ struct MenuContent: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.blue)
|
.foregroundColor(.blue)
|
||||||
}
|
}
|
||||||
|
.padding(8)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(Color.blue.opacity(0.05))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.padding(4)
|
|
||||||
}
|
}
|
||||||
.padding(4)
|
.padding(8)
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
@@ -185,7 +205,7 @@ struct MenuContent: View {
|
|||||||
}
|
}
|
||||||
.toggleStyle(.checkbox)
|
.toggleStyle(.checkbox)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.padding(4)
|
.padding(8)
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
@@ -197,7 +217,7 @@ struct MenuContent: View {
|
|||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.padding(4)
|
.padding(8)
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
@@ -208,7 +228,7 @@ struct MenuContent: View {
|
|||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.padding(4)
|
.padding(8)
|
||||||
}
|
}
|
||||||
.padding(12)
|
.padding(12)
|
||||||
.frame(minWidth: 280)
|
.frame(minWidth: 280)
|
||||||
@@ -239,6 +259,12 @@ struct MenuContent: View {
|
|||||||
window.title = "PowerBar 使用指南"
|
window.title = "PowerBar 使用指南"
|
||||||
window.contentView = NSHostingView(rootView: GuideView())
|
window.contentView = NSHostingView(rootView: GuideView())
|
||||||
window.center()
|
window.center()
|
||||||
|
|
||||||
|
// 设置初始窗口状态(透明且缩放)
|
||||||
|
window.alphaValue = 0.0
|
||||||
|
window.setFrameOrigin(window.frame.origin)
|
||||||
|
|
||||||
|
// 显示窗口(不可见状态)
|
||||||
window.makeKeyAndOrderFront(nil)
|
window.makeKeyAndOrderFront(nil)
|
||||||
|
|
||||||
// 记录已显示指引
|
// 记录已显示指引
|
||||||
@@ -256,6 +282,14 @@ struct MenuContent: View {
|
|||||||
// 窗口关闭时清除引用
|
// 窗口关闭时清除引用
|
||||||
guideWindow = nil
|
guideWindow = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 执行打开动画
|
||||||
|
NSAnimationContext.runAnimationGroup {
|
||||||
|
context in
|
||||||
|
context.duration = 0.5
|
||||||
|
context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||||
|
window.animator().alphaValue = 1.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +342,7 @@ struct GuideView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
Image(systemName: "power.on.circle")
|
Image(systemName: "power.circle")
|
||||||
.font(.title)
|
.font(.title)
|
||||||
.foregroundColor(.orange)
|
.foregroundColor(.orange)
|
||||||
.frame(width: 40)
|
.frame(width: 40)
|
||||||
@@ -403,8 +437,17 @@ struct GuideView: View {
|
|||||||
|
|
||||||
// 关闭按钮
|
// 关闭按钮
|
||||||
Button(action: {
|
Button(action: {
|
||||||
// 关闭指引界面
|
// 关闭指引界面,添加关闭动画
|
||||||
NSApp.keyWindow?.close()
|
if let window = NSApp.keyWindow {
|
||||||
|
NSAnimationContext.runAnimationGroup {
|
||||||
|
context in
|
||||||
|
context.duration = 0.3
|
||||||
|
context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||||
|
window.animator().alphaValue = 0.0
|
||||||
|
} completionHandler: {
|
||||||
|
window.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}) {
|
}) {
|
||||||
Text("开始使用")
|
Text("开始使用")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
@@ -415,6 +458,8 @@ struct GuideView: View {
|
|||||||
RoundedRectangle(cornerRadius: 8)
|
RoundedRectangle(cornerRadius: 8)
|
||||||
.fill(.blue)
|
.fill(.blue)
|
||||||
)
|
)
|
||||||
|
.transition(.scale(scale: 0.9, anchor: .center))
|
||||||
|
.animation(.easeInOut(duration: 0.2), value: UUID())
|
||||||
}
|
}
|
||||||
.padding(.bottom, 20)
|
.padding(.bottom, 20)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user