【问题标题】:How to differentiate between iphone4 and iphone 3如何区分iphone4和iphone 3
【发布时间】:2011-03-18 16:05:18
【问题描述】:

我正在尝试使用 cocos2d 引擎为 iphone 构建游戏。我想知道如何区分用户使用的是 iphone 4 还是 iphone 3,因为我想为 iphone4 加载高分辨率图形,为 iphone 3 加载低分辨率图形。我知道我是否使用@2x.png at如果我使用的是 iphone 4,图像文件名 UIImage 的末尾会自行加载高分辨率图像,但对于游戏,我使用 cocos2d 引擎的 CCSprite 类来加载图形。

非常感谢您的回复。

问候, 安库尔

【问题讨论】:

    标签: ios ccsprite


    【解决方案1】:

    您可以检查屏幕的比例。

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2){
        //iPhone 4
    }
    

    【讨论】:

    • 请注意,OS 3.2 中的 iPad 也可以使用缩放功能,而不仅仅是 iOS 4 上的。
    • 对,但 iPad 的比例不是 2。
    • 其实iPad在2倍缩放模式下的比例是2。
    • 但是,如果您在 iPad 上进行 2 倍变焦,那么提供更高分辨率的图形难道不是一个不错的奖励吗?
    • 如上面的 cmets 所述,这会在 iPad 3.2 上返回误报(但在 iOS4.x 设备上正常工作)。
    【解决方案2】:

    用于检测所有设备上的视网膜显示,包括新 iPad

        +(BOOL)isRetinaDisplay {
        // since we call this alot, cache it
        static CGFloat scale = 0.0;
        if (scale == 0.0) {
            // NOTE: In order to detect the Retina display reliably on all iOS devices,
            // you need to check if the device is running iOS4+ and if the 
            // [UIScreen mainScreen].scale property is equal to 2.0. 
            // You CANNOT assume a device is running iOS4+ if the scale property exists,
            // as the iPad 3.2 also contains this property.
            // On an iPad running iOS3.2, scale will return 1.0 in 1x mode, and 2.0
            // in 2x mode -- even though we know that device does not contain a Retina display.
            // Apple changed this behavior in iOS4.2 for the iPad: it returns 1.0 in both
            // 1x and 2x modes. You can test this yourself in the simulator.
            // I test for the -displayLinkWithTarget:selector: method on the main screen
            // which exists in iOS4.x but not iOS3.2, and then check the screen's scale:
    
            if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && 
                ([UIScreen mainScreen].scale == 2.0)) {
                scale = 2.0;
                return YES;
            } else {
                scale = 1.0;
                return NO;
            }   
    
        }
        return scale > 1.0;
    }
    

    感谢:阿德里亚诺·帕拉迪尼 http://developer.appcelerator.com/question/133826/detecting-new-ipad-3-dpi-and-retina

    【讨论】:

      【解决方案3】:
      - (NSString *) platform  
      {  
          size_t size;  
          sysctlbyname("hw.machine", NULL, &size, NULL, 0);  
          char *machine = malloc(size);  
          sysctlbyname("hw.machine", machine, &size, NULL, 0);  
          NSString *platform = [NSString stringWithCString:machine];  
          free(machine);  
          return platform;  
      }  
      
      - (NSString *) platformString  
      {  
          NSString *platform = [self platform];  
          if ([platform isEqualToString:@"iPhone1,1"]) return @"Original iPhone";  
          if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";  
          if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3G[S]"; 
          if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";   
          return @"Unknown";  
      }  
      

      【讨论】:

        【解决方案4】:

        尽管 Apple 的文档说了什么,但 UIScreen 的 scale 属性不仅在 iOS4 中可用,在 iPad 上的 3.2 中也可用。这意味着检查您使用的设备可能是一种不可靠的方法。

        相反,您应该检查 contentScaleFactor 在您的主窗口(或任何 UIView)上是否可用,然后检查比例值。

        【讨论】:

        • 不幸的是,contentScaleFactor 在 iOS 4 中也是新的,因此它对向后兼容性没有任何帮助,而不仅仅是 scale 属性。我想知道如果用户单击 iPad 上的“2x”按钮,它是否会即时从 1 变为 2?
        • 在 3.2 中可以,所以我认为在 4.2 中也可以,不过我还没有检查过。
        【解决方案5】:

        仅检查 scale 属性是不够的,因为在 iPad 3.2 的 2x 模式下,scale 属性存在并将返回 2.0,但我们知道该设备没有 Retina 显示屏。

        我已经在UIScreen 上创建了一个类别来执行此操作。有关更详细的说明,请参阅我对Detect Retina Display 的回答。代码如下:

        @interface UIScreen(ZBScreenRetinaAdditions)
        
        // Returns YES if this is a Retina display.
        - (BOOL)zb_isRetina;
        
        @end
        
        @implementation UIScreen(ZBScreenRetinaAdditions)
        
        - (BOOL)zb_isRetina {
          return [self respondsToSelector:@selector(displayLinkWithTarget:selector:)] && (self.scale == 2.0);
        }
        
        @end
        

        使用示例:

        if ([UIScreen mainScreen] zb_isRetina) {
          // Retina display
        }
        

        【讨论】:

        • 只是好奇...为什么最后有? YES : NO?在您的代码中没有必要,对吧?
        • 你说得对,没必要。这种风格是我第一次学习 Objective-C 时从一些例子中养成的一个坏习惯。固定。
        【解决方案6】:

        只需加上我的 2 美分:

        我知道你在这里做什么,但是将它绑定到一个特定的值,比如 2.0 目前是好的,但是如果下一个 iPad 得到像 x1.5 这样的分辨率提升呢?对我来说,任何高于 1.0 的显示都高于正常显示,因此我将加载高分辨率图形。如果那是 iPad、iPhone 没关系....

        【讨论】:

          【解决方案7】:

          我知道这个话题现在有点老了,但它可能会帮助一些人。 在 Cocos2d 上,您可以使用文件上的 -hd 后缀为 iphone4 加载高分辨率图形,为 iphone 3 加载低分辨率图形。

          你只需要像这样之前启用视网膜显示:

          // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
          if( ! [director enableRetinaDisplay:YES] )
              CCLOG(@"Retina Display Not supported");
          

          有关更多信息,请阅读此处的文档:RetinaDisplay in cocos2d

          【讨论】:

            【解决方案8】:

            导入“UIScreen+Retina.h”

            if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
                //IPAD        
                if ([[UIScreen mainScreen] isRetina]) {
                    // IPAD 3 - Retina display
                    bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPAD_HIGHRES;            
                }else{
                    //iPAD 1/2
                    bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPAD_LOWRES;        }
            }else{
                //IPHONE
                if ([[UIScreen mainScreen] isRetina]) {
                    // IPHONE 4/4s/5 - Retina display
                    bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPHONE_HIGHRES;
            
                }else{
                    //IPHONE (3.x)
                    bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPHONE_LOWRES;
            
                }
            }
            

            【讨论】:

              【解决方案9】:

              缩放适用于 iPad,但您始终可以使用 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 来检查它是 iPad 还是 iPhone/iTouch

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-05-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多