我可以使用两个xib和一个viewcontroller - re:移植到iPhone 5

Dal*_*ich 14 xib uiviewcontroller iphone-5

我刚刚将我的第一个应用程序提交到应用程序商店(但它刚被批准了!).我现在想要更新它以便在更大的iPhone 5屏幕上工作(看起来更好).除了为更大的屏幕稍微改变布局之外,我不打算改变任何其他内容.

注意:我不希望我的当前xib伸展.

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

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

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

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

如果是这样,我该怎么做呢?

Dal*_*ich 25

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

经过重大研究后,我找到了答案,部分是在这个SO页面上(显示了如何检测你的应用程序运行的iPhone版本)和部分这个SO页面(显示如何让两个xib共享相同的'文件所有者'.拼图的一部分(通过loadNibNamed:方法加载单独的xib)我在The Big Nerd Ranch的优秀iOS编程文本的第10章中找到.这是如何:

  1. 创建第二个xib(File,New ...,File,选择'User Interface',选择'Empty'并保存.这将创建新的xib.在下面的示例中,我的经典xib(用于3.5"iPhone)被命名TipMainViewController.xib.我保存了名为'TipMainViewController-5.xib'的新iPhone 5 xib

  2. 使新的xib的'文件所有者'与现有的xib相同的ViewController.为此,请在新的xib文件中选择"文件所有者".然后在"Identity Inspector"中选择现有的View Controller作为Custom Class.在我的例子中,我选择了'TipMainViewController'.

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

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

  5. 创建原始xib时,与File's Owner建立所有连接.

  6. 最后,在'single'ViewController的'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];
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 您的代码示例不起作用并包含拼写错误.目前还不清楚你的意思是`viewDidLoad`还是`loadView` (2认同)

Ili*_*rim 7

下面是一个简单,工作对您的视图控制器代码示例演示如何加载 myXib-5.xib在iPhone 5和myXib.xibiPhone上/ iPod播放器早于iPhone 5:

- (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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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


小智 6

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

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

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

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

  • ExampleViewController.xib [iphone默认为视网膜命名为空时为Retina 3.5全屏经典布局iphone 4/4s等...]
  • ExampleViewController~ipad.xib [当nib名为empty时,ipad/ipad mini默认]

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

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

  • ExampleViewController-568h.xib [当Retina 4全屏(568h)的笔尖名称为空时,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;
}
Run Code Online (Sandbox Code Playgroud)

的UIViewController + AppCategories.h

#import <UIKit/UIKit.h>

@interface UIViewController (AppCategories)

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

@end
Run Code Online (Sandbox Code Playgroud)

的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
Run Code Online (Sandbox Code Playgroud)