【问题标题】:How to get the current application icon in ios如何在ios中获取当前应用程序图标
【发布时间】:2012-03-14 05:23:59
【问题描述】:

有没有办法在 cocoa-touch 应用程序中获取当前应用程序图标? 谢谢。

【问题讨论】:

    标签: ios cocoa-touch nsbundle uiapplication


    【解决方案1】:

    只是为了澄清,这是您根据上面的示例查询 CFBundleIcon 字典时得到的结果:

    (key: "CFBundlePrimaryIcon", value: {
        CFBundleIconFiles =     (
            AppIcon60x60
        );
        CFBundleIconName = AppIcon;
    })
    

    不幸的是,只有两个值被返回。一个是我iPhone Mini上的AppIcon60x60,另一个是AppIcon更小!

    有人有其他提示吗?

    【讨论】:

      【解决方案2】:

      @samwize 提供的答案是正确的,对于 SwiftUI 应该是:

      Image(uiImage: Bundle.main.icon ?? UIImage())
      

      【讨论】:

        【解决方案3】:

        因为我花了一点时间来解决这个问题,所以这是一个有效的 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)
        

        【讨论】:

          【解决方案4】:

          适用于 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

          【讨论】:

          • 这只给了我 AppIcon60x60(在 iPhone7 上运行)或 AppIcon76x76(在 iPadPro 12.9" 第 4 代上运行)模拟器。还有其他方法可以访问更高分辨率的图像吗?我我的资产中的所有尺寸都高达 1024pt。
          • 哼。几乎只是在我回答后 3 年以上将我的回答调整为扩展,并被接受而不是我的回答。
          【解决方案5】:

          这是UIApplicationSwift 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 以获得最小和最大图标。

          【讨论】:

          • Swift 3 代码的第一行给出“Type 'Any' has no subscript members”
          • @Crazor 谢谢,当我在 beta 版本中测试时,该代码最初可以正常工作,但我看到了您报告的错误并更新了代码以正常工作。
          【解决方案6】:

          如果您使用的是 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 的调用要好。

          【讨论】:

            【解决方案7】:

            如果您使用资产目录,那么您可以简单地使用:

            UIImage* appIcon = [UIImage imageNamed:@"AppIcon60x60"];

            资产目录似乎标准化了应用程序图标的文件名。

            当然,如果您需要列出捆绑包中的所有应用程序图标,您可以在信息字典的CFBundleIconFiles 分支中查找。

            使用 KVC,您可以在一行代码中轻松实现:

            NSArray* allIcons = [[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"];
            

            结果数组将包含捆绑包中可用的所有应用图标名称。这些名称中的任何一个都可用于使用+[UIImage imageNamed:]检索图标

            <__NSCFArray 0x15d54260>(
                AppIcon29x29,
                AppIcon40x40,
                AppIcon60x60
            )
            

            【讨论】:

            • '这是最好的答案!感谢在 2020 年完美运行 :)
            【解决方案8】:

            接受的答案对我不起作用,我正在使用 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]];
            • 你应该选择 lastObject 以获得更好的质量。
            【解决方案9】:

            我的答案完全基于moosgummi's,但返回的是UIImage

            UIImage *appIcon = [UIImage imageNamed: [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];
            

            UIImage 自动选择合适的版本(普通、@2x~ipad~ipad@2x 或任何未来的后缀)。 (顺便说一句,你不只是讨厌这种用于识别图像版本的愚蠢方案吗?它已经失控了。感谢上帝的资产目录!)

            【讨论】:

            • 我可以确认 UIImage imageNamed 确实调用了适当的 @2x 文件。注意:比例因子会修改图像的大小。
            • 其实这个方案确实省了很多工作。我唯一不喜欢的是应用程序的大小,其中包含针对不同设备的多个图像。不知道 App Store 是否足够聪明,可以在支持视网膜等情况下仅提供 @2x 图像。
            【解决方案10】:

            这是在 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 显示选择合适的图标。

            希望对你有帮助!

            【讨论】:

              【解决方案11】:

              这很简单,因为当前图标的文件名是在 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 对象。如果没有,你的应用配置有问题。
              • 调用objectForKey返回id,有时候id的类型确实是NSString而不是NSArray,也许这就是问题所在。
              猜你喜欢
              • 2012-04-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-07-21
              • 2012-11-26
              • 2019-01-06
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多