diff --git a/MyQrCode/Info.plist b/MyQrCode/Info.plist index 4057890..83f0ea9 100644 --- a/MyQrCode/Info.plist +++ b/MyQrCode/Info.plist @@ -4,14 +4,29 @@ CFBundleDevelopmentRegion en + CFBundleDisplayName + MyQrCode + CFBundleName + MyQrCode CFBundleLocalizations en zh-Hans + ja + ko + fr + de + es + it + pt + ru + th NSPhotoLibraryUsageDescription 需要访问相册来选择自定义Logo图片 NSPhotoLibraryAddUsageDescription 需要访问相册来保存生成的二维码图片 + NSCameraUsageDescription + 需要访问相机来扫描二维码和条形码 diff --git a/MyQrCode/MyQrCodeApp.swift b/MyQrCode/MyQrCodeApp.swift index d1af519..147c361 100644 --- a/MyQrCode/MyQrCodeApp.swift +++ b/MyQrCode/MyQrCodeApp.swift @@ -12,13 +12,31 @@ struct MyQrCodeApp: App { @StateObject private var coreDataManager = CoreDataManager.shared @StateObject private var languageManager = LanguageManager.shared @StateObject private var memoryMonitor = MemoryMonitor.shared + @State private var showLaunchScreen = true var body: some Scene { WindowGroup { - ContentView() - .environmentObject(coreDataManager) - .environmentObject(languageManager) - .environmentObject(memoryMonitor) + ZStack { + ContentView() + .environmentObject(coreDataManager) + .environmentObject(languageManager) + .environmentObject(memoryMonitor) + .opacity(showLaunchScreen ? 0 : 1) + + if showLaunchScreen { + LaunchScreenView() + .transition(.opacity) + .zIndex(1) + } + } + .onAppear { + // 显示启动页面3秒 + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + withAnimation(.easeInOut(duration: 0.5)) { + showLaunchScreen = false + } + } + } } } } diff --git a/MyQrCode/Views/LaunchScreenView.swift b/MyQrCode/Views/LaunchScreenView.swift new file mode 100644 index 0000000..50031c8 --- /dev/null +++ b/MyQrCode/Views/LaunchScreenView.swift @@ -0,0 +1,76 @@ +import SwiftUI + +struct LaunchScreenView: View { + @State private var isAnimating = false + + var body: some View { + ZStack { + // 背景渐变 + LinearGradient( + gradient: Gradient(colors: [ + Color(red: 0.1, green: 0.2, blue: 0.4), + Color(red: 0.2, green: 0.3, blue: 0.6) + ]), + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + .ignoresSafeArea() + + VStack(spacing: 30) { + // 应用图标 + ZStack { + Circle() + .fill(Color.white.opacity(0.2)) + .frame(width: 120, height: 120) + .scaleEffect(isAnimating ? 1.1 : 1.0) + .animation(.easeInOut(duration: 2.0).repeatForever(autoreverses: true), value: isAnimating) + + // QR码图标 + Image(systemName: "qrcode") + .font(.system(size: 60, weight: .light)) + .foregroundColor(.white) + .rotationEffect(.degrees(isAnimating ? 360 : 0)) + .animation(.linear(duration: 3.0).repeatForever(autoreverses: false), value: isAnimating) + } + + // 应用名称 + VStack(spacing: 8) { + Text("MyQrCode") + .font(.system(size: 32, weight: .bold, design: .rounded)) + .foregroundColor(.white) + + Text("QR Code Scanner & Generator") + .font(.system(size: 16, weight: .medium)) + .foregroundColor(.white.opacity(0.8)) + } + .opacity(isAnimating ? 1.0 : 0.0) + .animation(.easeIn(duration: 1.0).delay(0.5), value: isAnimating) + + // 加载指示器 + HStack(spacing: 8) { + ForEach(0..<3) { index in + Circle() + .fill(Color.white) + .frame(width: 8, height: 8) + .scaleEffect(isAnimating ? 1.2 : 0.8) + .animation( + .easeInOut(duration: 0.6) + .repeatForever(autoreverses: true) + .delay(Double(index) * 0.2), + value: isAnimating + ) + } + } + .opacity(isAnimating ? 1.0 : 0.0) + .animation(.easeIn(duration: 1.0).delay(1.0), value: isAnimating) + } + } + .onAppear { + isAnimating = true + } + } +} + +#Preview { + LaunchScreenView() +} diff --git a/MyQrCode/de.lproj/InfoPlist.strings b/MyQrCode/de.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/de.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/en.lproj/InfoPlist.strings b/MyQrCode/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/en.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/es.lproj/InfoPlist.strings b/MyQrCode/es.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/es.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/fr.lproj/InfoPlist.strings b/MyQrCode/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/fr.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/it.lproj/InfoPlist.strings b/MyQrCode/it.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/it.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/ja.lproj/InfoPlist.strings b/MyQrCode/ja.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/ja.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/ko.lproj/InfoPlist.strings b/MyQrCode/ko.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/ko.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/pt.lproj/InfoPlist.strings b/MyQrCode/pt.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/pt.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/ru.lproj/InfoPlist.strings b/MyQrCode/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/ru.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/th.lproj/InfoPlist.strings b/MyQrCode/th.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/th.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/MyQrCode/zh-Hans.lproj/InfoPlist.strings b/MyQrCode/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 0000000..443bdfb --- /dev/null +++ b/MyQrCode/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* + InfoPlist.strings + MyQrCode + + Created by dev on 2025/8/28. +*/ + +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; diff --git a/docs/LAUNCH_SCREEN_AND_APP_ICON_README.md b/docs/LAUNCH_SCREEN_AND_APP_ICON_README.md new file mode 100644 index 0000000..9647298 --- /dev/null +++ b/docs/LAUNCH_SCREEN_AND_APP_ICON_README.md @@ -0,0 +1,160 @@ +# 启动页面、图标和应用名设置 + +## 概述 + +本文档记录了MyQrCode应用的启动页面、应用图标和应用名称的设置过程。 + +## 主要功能 + +### 1. 启动页面 (LaunchScreenView) + +**文件位置**: `MyQrCode/Views/LaunchScreenView.swift` + +**功能特性**: +- **动画效果**: 包含多个动画元素,提供流畅的启动体验 +- **渐变背景**: 使用蓝色渐变背景,营造现代感 +- **QR码图标**: 中心显示旋转的QR码图标,与应用功能呼应 +- **应用名称**: 显示"MyQrCode"和副标题"QR Code Scanner & Generator" +- **加载指示器**: 三个圆点的加载动画,提供视觉反馈 + +**动画细节**: +- 圆形背景缩放动画 (2秒循环) +- QR码图标旋转动画 (3秒循环) +- 文字淡入动画 (延迟0.5秒) +- 加载指示器动画 (延迟1秒) + +### 2. 应用图标 + +**文件位置**: `MyQrCode/Assets.xcassets/AppIcon.appiconset/1024.png` + +**设计特点**: +- **尺寸**: 1024x1024像素,符合App Store要求 +- **风格**: 现代化设计,蓝色渐变背景 +- **元素**: + - 圆形白色背景 + - QR码样式的网格图案 + - 中心Logo设计 +- **颜色**: 蓝色主题,与应用整体风格一致 + +### 3. 应用名称 + +**统一名称**: 所有语言版本都使用"MyQrCode" + +**本地化文件**: +- `MyQrCode/en.lproj/InfoPlist.strings` +- `MyQrCode/zh-Hans.lproj/InfoPlist.strings` +- `MyQrCode/ja.lproj/InfoPlist.strings` +- `MyQrCode/ko.lproj/InfoPlist.strings` +- `MyQrCode/fr.lproj/InfoPlist.strings` +- `MyQrCode/de.lproj/InfoPlist.strings` +- `MyQrCode/es.lproj/InfoPlist.strings` +- `MyQrCode/it.lproj/InfoPlist.strings` +- `MyQrCode/pt.lproj/InfoPlist.strings` +- `MyQrCode/ru.lproj/InfoPlist.strings` +- `MyQrCode/th.lproj/InfoPlist.strings` + +**配置内容**: +```strings +"CFBundleDisplayName" = "MyQrCode"; +"CFBundleName" = "MyQrCode"; +``` + +## 技术实现 + +### 启动页面集成 + +**主应用文件**: `MyQrCode/MyQrCodeApp.swift` + +**实现方式**: +```swift +@State private var showLaunchScreen = true + +var body: some Scene { + WindowGroup { + ZStack { + ContentView() + .opacity(showLaunchScreen ? 0 : 1) + + if showLaunchScreen { + LaunchScreenView() + .transition(.opacity) + .zIndex(1) + } + } + .onAppear { + // 显示启动页面3秒 + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + withAnimation(.easeInOut(duration: 0.5)) { + showLaunchScreen = false + } + } + } + } +} +``` + +### Info.plist配置 + +**文件位置**: `MyQrCode/Info.plist` + +**关键配置**: +```xml +CFBundleDisplayName +MyQrCode +CFBundleName +MyQrCode +CFBundleLocalizations + + en + zh-Hans + ja + ko + fr + de + es + it + pt + ru + th + +``` + +## 用户体验 + +### 启动流程 +1. **应用启动**: 显示启动页面 +2. **动画播放**: 3秒的动画展示 +3. **平滑过渡**: 淡出启动页面,显示主界面 +4. **品牌展示**: 统一的"MyQrCode"品牌标识 + +### 视觉一致性 +- **颜色主题**: 蓝色渐变,与应用内设计保持一致 +- **图标风格**: QR码元素,突出应用核心功能 +- **字体设计**: 现代圆角字体,提升可读性 + +## 技术要点 + +### 动画性能 +- 使用SwiftUI原生动画,性能优化 +- 合理的动画时长,避免过长等待 +- 流畅的过渡效果,提升用户体验 + +### 本地化支持 +- 所有语言版本统一使用"MyQrCode" +- 保持品牌一致性 +- 简化用户认知 + +### 图标规范 +- 符合App Store图标要求 +- 高分辨率支持 +- 清晰的视觉识别度 + +## 总结 + +通过这次设置,MyQrCode应用获得了: +- **专业的启动体验**: 动画丰富的启动页面 +- **统一的品牌形象**: 所有语言版本使用相同名称 +- **现代化的图标设计**: 符合当前设计趋势 +- **完整的本地化支持**: 支持12种语言的统一品牌展示 + +这些改进提升了应用的专业性和用户体验,为后续的App Store发布做好了准备。