From 2afedafb8a8f49fef2aecfdfc56ef079964f1063 Mon Sep 17 00:00:00 2001 From: v504 Date: Thu, 28 Aug 2025 17:47:29 +0800 Subject: [PATCH] Enhance app launch experience by introducing a launch screen that displays for 3 seconds before transitioning to the main content. Update Info.plist to include new app display name and additional localization support for Japanese, Korean, French, German, Spanish, Italian, Portuguese, Russian, and Thai. Add camera usage description for QR code scanning functionality. --- MyQrCode/Info.plist | 15 ++ MyQrCode/MyQrCodeApp.swift | 26 +++- MyQrCode/Views/LaunchScreenView.swift | 76 ++++++++++ MyQrCode/de.lproj/InfoPlist.strings | 9 ++ MyQrCode/en.lproj/InfoPlist.strings | 9 ++ MyQrCode/es.lproj/InfoPlist.strings | 9 ++ MyQrCode/fr.lproj/InfoPlist.strings | 9 ++ MyQrCode/it.lproj/InfoPlist.strings | 9 ++ MyQrCode/ja.lproj/InfoPlist.strings | 9 ++ MyQrCode/ko.lproj/InfoPlist.strings | 9 ++ MyQrCode/pt.lproj/InfoPlist.strings | 9 ++ MyQrCode/ru.lproj/InfoPlist.strings | 9 ++ MyQrCode/th.lproj/InfoPlist.strings | 9 ++ MyQrCode/zh-Hans.lproj/InfoPlist.strings | 9 ++ docs/LAUNCH_SCREEN_AND_APP_ICON_README.md | 160 ++++++++++++++++++++++ 15 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 MyQrCode/Views/LaunchScreenView.swift create mode 100644 MyQrCode/de.lproj/InfoPlist.strings create mode 100644 MyQrCode/en.lproj/InfoPlist.strings create mode 100644 MyQrCode/es.lproj/InfoPlist.strings create mode 100644 MyQrCode/fr.lproj/InfoPlist.strings create mode 100644 MyQrCode/it.lproj/InfoPlist.strings create mode 100644 MyQrCode/ja.lproj/InfoPlist.strings create mode 100644 MyQrCode/ko.lproj/InfoPlist.strings create mode 100644 MyQrCode/pt.lproj/InfoPlist.strings create mode 100644 MyQrCode/ru.lproj/InfoPlist.strings create mode 100644 MyQrCode/th.lproj/InfoPlist.strings create mode 100644 MyQrCode/zh-Hans.lproj/InfoPlist.strings create mode 100644 docs/LAUNCH_SCREEN_AND_APP_ICON_README.md 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发布做好了准备。