【发布时间】:2012-03-14 05:23:59
【问题描述】:
有没有办法在 cocoa-touch 应用程序中获取当前应用程序图标? 谢谢。
【问题讨论】:
标签: ios cocoa-touch nsbundle uiapplication
有没有办法在 cocoa-touch 应用程序中获取当前应用程序图标? 谢谢。
【问题讨论】:
标签: ios cocoa-touch nsbundle uiapplication
只是为了澄清,这是您根据上面的示例查询 CFBundleIcon 字典时得到的结果:
(key: "CFBundlePrimaryIcon", value: {
CFBundleIconFiles = (
AppIcon60x60
);
CFBundleIconName = AppIcon;
})
不幸的是,只有两个值被返回。一个是我iPhone Mini上的AppIcon60x60,另一个是AppIcon更小!
有人有其他提示吗?
【讨论】:
@samwize 提供的答案是正确的,对于 SwiftUI 应该是:
Image(uiImage: Bundle.main.icon ?? UIImage())
【讨论】:
因为我花了一点时间来解决这个问题,所以这是一个有效的 Swift 解决方案。
let primaryIconsDictionary = NSBundle.mainBundle().infoDictionary?["CFBundleIcons"]?["CFBundlePrimaryIcon"] as? NSDictionary
let iconFiles = primaryIconsDictionary!["CFBundleIconFiles"] as NSArray
let lastIcon = iconFiles.lastObject as NSString //last seems to be largest, use first for smallest
let theIcon = UIImage(named: lastIcon)
let iconImageView = UIImageView(image: theIcon)
【讨论】:
适用于 Swift 4.1 并将其扩展至 Bundle。
extension Bundle {
public var icon: UIImage? {
if let icons = infoDictionary?["CFBundleIcons"] as? [String: Any],
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
let lastIcon = iconFiles.last {
return UIImage(named: lastIcon)
}
return nil
}
}
要在应用中使用,请致电Bundle.main.icon。
【讨论】:
这是UIApplication 的Swift 4.x && 3.x 扩展,用于获取应用程序图标。您可以根据从iconFiles 数组中拉取的图标路径的位置来选择是获取最小图标还是获取最大图标。
extension UIApplication {
var icon: UIImage? {
guard let iconsDictionary = Bundle.main.infoDictionary?["CFBundleIcons"] as? NSDictionary,
let primaryIconsDictionary = iconsDictionary["CFBundlePrimaryIcon"] as? NSDictionary,
let iconFiles = primaryIconsDictionary["CFBundleIconFiles"] as? NSArray,
// First will be smallest for the device class, last will be the largest for device class
let lastIcon = iconFiles.lastObject as? String,
let icon = UIImage(named: lastIcon) else {
return nil
}
return icon
}
}
要访问图标,请调用以下命令:
let icon = UIApplication.shared.icon
如果您的应用需要,您甚至可以制作两个 var 以获得最小和最大图标。
【讨论】:
如果您使用的是 Xamarin:
var iconNames = NSBundle.MainBundle.InfoDictionary.ValueForKeyPath((NSString)"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles") as NSArray;
var name = iconNames.GetItem<NSString>(iconNames.Count - 1); //Grabs last item, call with 0 for the first item
var icon = UIImage.FromBundle(name);
基于Andy's answer使用KVC方法。有点冗长,但使用 KeyPath 比链接对 ValueForKey 的调用要好。
【讨论】:
如果您使用资产目录,那么您可以简单地使用:
UIImage* appIcon = [UIImage imageNamed:@"AppIcon60x60"];
资产目录似乎标准化了应用程序图标的文件名。
当然,如果您需要列出捆绑包中的所有应用程序图标,您可以在信息字典的CFBundleIconFiles 分支中查找。
使用 KVC,您可以在一行代码中轻松实现:
NSArray* allIcons = [[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"];
结果数组将包含捆绑包中可用的所有应用图标名称。这些名称中的任何一个都可用于使用+[UIImage imageNamed:]检索图标
<__NSCFArray 0x15d54260>(
AppIcon29x29,
AppIcon40x40,
AppIcon60x60
)
【讨论】:
接受的答案对我不起作用,我正在使用 Xcode 5 的 Images.xcassets 存储应用程序图标的方法。这个修改对我有用:
UIImage *appIcon = [UIImage imageNamed: [[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIcons"] objectForKey:@"CFBundlePrimaryIcon"] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];
如有疑问,只需使用 lldb 探索主包的 infoDictionary。
【讨论】:
UIImage *appIcon = [UIImage imageNamed:[[NSBundle mainBundle].infoDictionary[@"CFBundleIcons"][@"CFBundlePrimaryIcon"][@"CFBundleIconFiles"] firstObject]];
我的答案完全基于moosgummi's,但返回的是UIImage。
UIImage *appIcon = [UIImage imageNamed: [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];
UIImage 自动选择合适的版本(普通、@2x、~ipad、~ipad@2x 或任何未来的后缀)。 (顺便说一句,你不只是讨厌这种用于识别图像版本的愚蠢方案吗?它已经失控了。感谢上帝的资产目录!)
【讨论】:
这是在 info.plist 中设置图标的方式,
//try doing NSLog(@"%@",[[NSBundle mainBundle] infoDictionary]);
CFBundleIcons = {
CFBundlePrimaryIcon = {
CFBundleIconFiles = (
"icon.png",//App icon added by you
"icon@2x.png"//App icon in retina added by you
);
UIPrerenderedIcon = 1;
};
};
如果您想获取应用程序图标,请使用以下代码:
UIImage *appIcon = [UIImage imageNamed: [[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIcons"] objectForKey:@"CFBundlePrimaryIcon"] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];
P.S:UIImage 会自动为 Retina 显示选择合适的图标。
希望对你有帮助!
【讨论】:
这很简单,因为当前图标的文件名是在 Info.plist 中设置的:
NSString *filePath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];
如果你想选择你应该使用的高分辨率版本:
NSString *filePath = nil;
for (NSString *fileName in [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"]) {
if ([fileName rangeOfString:@"@2x"].location != NSNotFound) {
filePath = [[NSString alloc] initWithString:fileName];
}
}
【讨论】:
NSLog([NSBundle mainBundle] infoDictionary]); 找出是否有CFBundleIconFiles 对象。如果没有,你的应用配置有问题。