所有 App 圖標與啟動圖資訊均儲存於 `Info.plist`,通過 `[[NSBundle mainBundle] infoDictionary]` 獲取:
- (NSString *)primaryIconName {
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
NSArray *iconFiles = infoDict[@"CFBundleIcons"][@"CFBundlePrimaryIcon"][@"CFBundleIconFiles"];
// 最後一個通常為最高解析度(如 AppIcon60x60@3x)
return iconFiles.lastObject;
}
// 打印所有 Icon 檔名
NSLog(@"Icon files: %@", iconFiles);
// 輸出: ( "AppIcon29x29", "AppIcon40x40", "AppIcon60x60", "AppIcon76x76", "AppIcon83.5x83.5" )
- (NSString *)launchImageNameForCurrentDevice {
CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
BOOL isPortrait = UIInterfaceOrientationIsPortrait(orientation);
BOOL isLandscape = UIInterfaceOrientationIsLandscape(orientation);
NSString *name = nil;
if ((isPortrait && screenH == 480) || (isLandscape && screenW == 480)) {
name = @"LaunchImage-700"; // iPhone 4/4S
} else if ((isPortrait && screenH == 568) || (isLandscape && screenW == 568)) {
name = @"LaunchImage-700-568h"; // iPhone 5/5s/SE1
} else if ((isPortrait && screenH == 667) || (isLandscape && screenW == 667)) {
name = @"LaunchImage-800-667h"; // iPhone 6/6s/7/8/SE2/SE3
} else if (isPortrait && screenH == 736) {
name = @"LaunchImage-800-Portrait-736h"; // 6/7/8 Plus 豎屏
} else if (isLandscape && screenW == 736) {
name = @"LaunchImage-800-Landscape-736h"; // Plus 橫屏
} else if (isPortrait && screenH == 1024) {
name = @"LaunchImage-700-Portrait"; // iPad 豎屏
} else if (isLandscape && screenW == 1024) {
name = @"LaunchImage-700-Landscape"; // iPad 橫屏
}
// 刘海屏、iPad Pro 等需補充對應尺寸
return name;
}
// 用法:設置為背景圖
UIImage *img = [UIImage imageNamed:[self launchImageNameForCurrentDevice]];
self.view.backgroundColor = [UIColor colorWithPatternImage:img];
- (NSString *)launchImageNameFromPlist {
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
NSArray *launchImages = infoDict[@"UILaunchImages"];
CGSize screenSize = [UIScreen mainScreen].bounds.size;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
NSString *orientationStr = UIInterfaceOrientationIsPortrait(orientation) ? @"Portrait" : @"Landscape";
for (NSDictionary *imgInfo in launchImages) {
CGSize size = CGSizeFromString(imgInfo[@"UILaunchImageSize"]);
NSString *imgOrientation = imgInfo[@"UILaunchImageOrientation"];
// 匹配尺寸與方向(寬高需考慮縮放比例)
if (CGSizeEqualToSize(size, screenSize) && [imgOrientation isEqualToString:orientationStr]) {
return imgInfo[@"UILaunchImageName"];
}
}
return nil;
}
UILaunchImages = (
{
UILaunchImageMinimumOSVersion = "8.0";
UILaunchImageName = "LaunchImage-800-Portrait-736h";
UILaunchImageOrientation = Portrait;
UILaunchImageSize = "{414, 736}";
},
{
UILaunchImageMinimumOSVersion = "7.0";
UILaunchImageName = "LaunchImage-700-Portrait";
UILaunchImageOrientation = Portrait;
UILaunchImageSize = "{768, 1024}";
},
...
);
| Key | 含義 | 示例值 |
|---|---|---|
| CFBundleIcons | App Icon 定義 | 含 CFBundlePrimaryIcon → CFBundleIconFiles |
| UILaunchImages | 靜態啟動圖陣列 | 每項含 Name/Size/Orientation/MinOS |
| UILaunchStoryboardName | 啟動畫面 Storyboard | LaunchScreen (iOS 8+ 推薦) |
| UIDeviceFamily | 支援裝置類型 | 1=iPhone, 2=iPad |
| UISupportedInterfaceOrientations | 支援旋轉方向 | Portrait, LandscapeLeft, LandscapeRight |
| CFBundleShortVersionString | 用戶可見版本號 | 1.2.3 |
| CFBundleVersion | 構建版本號 | 100 |
iOS 8+ 強烈建議使用 LaunchScreen.storyboard 替代靜態圖片集:
/* LaunchScreen.storyboard 典型結構 */
- View Controller
- View (背景色/圖片)
- Image View (Logo, 居中約束)
- Label (版本號, 底部約束)
| 場景 | 解決方案 |
|---|---|
| 前台收到推送,模擬通知欄顯示 Icon | 用 `primaryIconName` 獲取圖標名,`[UIImage imageNamed:]` 載入 |
| 啟動頁廣告頁面,需無縫銜接 Launch Image | 解析 `UILaunchImages` 獲取當前裝置對應圖片名,設置為 `UIImageView` 圖片 |
| 動態更換 App Icon (iOS 10.3+) | `[UIApplication sharedApplication] setAlternateIconName:@"AltIcon"]`,圖標需預先在 `CFBundleAlternateIcons` 配置 |
| 適配 iPad 分屏多任務 | LaunchScreen.storyboard 自動適配;靜態圖需提供所有尺寸組合 |