15

我刚刚向应用商店提交了我的第一个应用程序(是的,它刚刚获得批准!)。我现在想更新它以使用(看起来更好)更大的 iPhone 5 屏幕。除了为更大的屏幕稍微改变布局之外,我不打算改变任何东西。

注意:我不想让我当前的 xib 被拉伸。

是否可以创建两个 xib 文件(即:为主屏幕复制我当前的 xib 文件)并将它们都连接到视图控制器并拥有它,以便在应用程序启动时,应用程序检测是否有 iPhone 5 屏幕或较早的屏幕。然后,根据设备的不同,向用户显示不同的屏幕。

我打算让底层应用程序保持不变。我只想为 iPhone 5 用户呈现一个稍微不同(更高)的屏幕,并为新布局移动一些按钮/项目。否则我不会在界面中添加或删除任何内容。

这个 SO question/answer显示了如何在 iPhone 或 iPad 视图之间切换。所以要做这个。两者都有帮助,但我不知道如何针对用户使用更大屏幕的 iPhone 5 或 iPhone 4S 及以下的情况进行修改。此外,他们假设有两个视图控制器。我只想要一个视图控制器,因为视图控制器逻辑中绝对没有任何变化 - 只有屏幕上对象的位置发生变化,而这一切都在 XIB 中完成。

我应该认为答案应该是视图控制器iteslf评估它正在运行的设备然后呈现适当的xib?是的?不?

如果是这样,我将如何处理?

4

3 回答 3

25

[完整答案于 2012 年 10 月 7 日修订]

经过大量研究后,我找到了答案,部分在此 SO 页面(显示如何检测您的应用程序正在运行的 iPhone 版本)和部分在此 SO 页面(显示如何让两个 xib 共享相同的 'File's Owner'。最后我在The Big Nerd Ranch 的优秀 iOS 编程文本的第 10 章中找到了一个难题(通过 loadNibNamed: 方法加载单独的 xib)。方法如下:

  1. 创建第二个 xib(文件,新建...,文件,选择“用户界面”,选择“空”并保存。这将创建新的 xib。在下面的示例中,我的经典 xib(适用于 3.5 英寸 iPhone)被命名为TipMainViewController.xib. 我保存了名为“TipMainViewController-5.xib”的新 iPhone 5 xib

  2. 使新 xib 的“文件所有者”与现有 xib 相同的 ViewController。为此,在新的 xib 文件中,选择“文件的所有者”。然后在“身份检查器”中选择现有的视图控制器作为自定义类。就我而言,我选择了“TipMainViewController”。

  3. 将新的 UIView 拖到新的 xib 的空画布上。在新 UIView 的属性检查器中,将“Size”属性设置为“Retina 4 Full Screen”

  4. 选择现有 'Classic' 3.5" xib 中的所有内容 - 例如:所有控件、按钮、选择器、标签等。将它们复制并粘贴到新的 iPhone 5 xib 中。调整大小/移动等以优化 iPhone 的4" 显示屏。

  5. 像创建原始 xib 时那样建立与文件所有者的所有连接。

  6. 最后,在“单个”视图控制器的“viewDidLoad”方法中,插入以下逻辑(当然使用您的 nib/xib 名称):

    - (void)loadView
    {
        [super viewDidLoad];
        if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        {
            CGSize result = [[UIScreen mainScreen] bounds].size;
            if(result.height == 480)
            {
              // iPhone Classic
              [[NSBundle mainBundle] loadNibNamed:@"TipMainViewController" owner:self options:nil];
            }
            if(result.height == 568)
            {
              // iPhone 5
              [[NSBundle mainBundle] loadNibNamed:@"TipMainViewController-5" owner:self options:nil];
            }
        }
    }
    
于 2012-10-01T23:19:20.160 回答
7

这是一个用于视图控制器的简单工作代码示例,展示了如何 myXib-5.xib在 iPhone 5 和myXib.xib早于 iPhone 5 的 iPhone/iPod 上加载:

- (void)loadView
{
    if([[UIScreen mainScreen] bounds].size.height == 568)
    {
        // iPhone 5
        self.view = [[NSBundle mainBundle] loadNibNamed:@"myXib-5" owner:self options:nil][0];
    }
    else
    {
        self.view = [[NSBundle mainBundle] loadNibNamed:@"myXib" owner:self options:nil][0];
    }
}

它假设您只针对 iPhone 而不是 iPad,以保持简单。

XIB 的文件所有者的类属性也应该设置为包含loadView.

于 2013-02-02T01:05:20.667 回答
6

回答中的代码很有帮助,但我需要一些更适合通用应用程序(iphone/ipad)的东西。

如果其他人需要同样的东西,这里有一些东西可以帮助你入门。

假设您使用 ios 的 nib/xib 命名标准为具有相同名称的 xib 的视图控制器构建了一个通用应用程序:

不提供名称时自动加载 xib 的两个内置默认值被传递给 initWithNibName:

  • ExampleViewController.xib [当 nib 为 Retina 3.5 Full Screen 为经典布局 iphone 4/4s 等命名为空时,iphone 默认...]
  • ExampleViewController~ipad.xib [ipad/ipad mini 默认当 nib 命名为空时]

现在假设您需要使用 Retina 4 全屏选项在 IB 中为 iphone 5/5s 自定义 xib,即,您不希望为任何 568h 设备显示 3.5 xib。

这是使用类别方法的自定义命名约定:

  • ExampleViewController-568h.xib [当 Retina 4 全屏 (568h) 的 nib 名称为空时,iphone 非默认/自定义命名约定]

不要覆盖内置的命名默认值,而是使用类别来帮助为控制器设置正确的 xib。

https://gist.github.com/scottvrosenthal/4945884

ExampleViewController.m

#import "UIViewController+AppCategories.h"

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    nibNameOrNil = [UIViewController nibNamedForDevice:@"ExampleViewController"];

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

       // Do any additional customization 

    }

    return self;
}

UIViewController+AppCategories.h

#import <UIKit/UIKit.h>

@interface UIViewController (AppCategories)

   + (NSString*)nibNamedForDevice:(NSString*)name;

@end

UIViewController+AppCategories.m

// ExampleViewController.xib [iphone default when nib named empty for Retina 3.5 Full Screen]
// ExampleViewController-568h.xib [iphone custom naming convention when nib named empty for Retina 4 Full Screen (568h)]
// ExampleViewController~ipad.xib [ipad/ipad mini default when nib named empty]

#import "UIViewController+AppCategories.h"

@implementation UIViewController (AppCategories)

+ (NSString*)nibNamedForDevice:(NSString*)name
{

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        if ([UIScreen mainScreen].bounds.size.height == 568)
        {
            //Check if there's a path extension or not
            if (name.pathExtension.length) {
                name = [name stringByReplacingOccurrencesOfString: [NSString stringWithFormat:@".%@", name.pathExtension] withString: [NSString stringWithFormat:@"-568h.%@", name.pathExtension ]
                ];

            } else {
                name = [name stringByAppendingString:@"-568h"];
            }

            // if 568h nib is found
            NSString *nibExists = [[NSBundle mainBundle] pathForResource:name ofType:@"nib"];
            if (nibExists) {
                return name;
           }

        }
    }

    // just default to ios universal app naming convention for xibs
    return Nil;
}

@end
于 2013-02-13T17:28:29.737 回答