【问题标题】:Unable to load two nib (.XIB) for Single ViewController class in Xcode 4.5 [duplicate]无法在 Xcode 4.5 中为 Single ViewController 类加载两个 nib (.XIB) [重复]
【发布时间】:2013-04-05 20:36:31
【问题描述】:

抱歉各位,我知道已经有很多类似的问题可用。我尝试了所有解决方案,但没有一个适合我。

我正在使用 Xcode 4.5.2 并为 iphone5/ios6 1> RootViewController5 和所有其他设备 2> RootViewController 使用两个 xib,这两个 nib 文件都有一个ViewController 名为 RootViewController。在两个 nib 文件的文件所有者中,我在自定义类检查器中选择了 RootViewController 类。

现在在 ViewDidLoad 方法中,我尝试像这样加载两个笔尖

 if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        UIViewController *viewController3;
        if(result.height == 480)
        {
          viewController3 = [[[UIViewController alloc] initWithNibName:@"RootViewController" bundle:nil] autorelease];
        }
        if(result.height == 568)
        {
        viewController3 = [[[UIViewController alloc] initWithNibName:@"RootViewController5" bundle:nil] autorelease];

            NSLog(@"iphone 5 123");
        }
    }

我也试过下面的代码

 if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        RootViewController *viewController3;
        if(result.height == 480)
        {
          viewController3 = [[[UIViewController alloc] initWithNibName:@"RootViewController" bundle:nil] autorelease];
        }
        if(result.height == 568)
        {
        viewController3 = [[[UIViewController alloc] initWithNibName:@"RootViewController5" bundle:nil] autorelease];

            NSLog(@"iphone 5 123");
        }
    }

但没有运气。请告知我在哪里弄错了。

谢谢

马尤尔

【问题讨论】:

  • 我不确定。为什么要在 viewDidLoad 中实例化控制器?你要把它推到 Nav 或 TabBar 控制器上吗?你能准确描述一下你得到了什么吗?另外 - 只是我的意见 - 但如果你想考虑 iPhone 模型,你最好不要为每个实例实例化一个 VC....这会产生大量代码重复,维护将是一场噩梦.
  • @Alex 其实我想做的是将我的应用程序迁移到 iOS 5 到 iOS 并与 iphone5 的屏幕尺寸兼容。因此,我为 iphone5 创建了单独的 XIB,所以如果它是不同的设备,那么将加载具有不同外观和感觉的不同 XIB。
  • 请注意那些希望将其作为副本关闭的人:前两个候选副本是关于命名 .xib 文件以在 iPad 和 iPhone 上自动加载。查看提供的 Apple 链接,他们并没有说这个命名方案适用于 iPhone5,这是这个问题所需要的。如果是这样 -> 不是这些问题的重复。
  • @gaige Brain 和 Nate 我在我的问题开始时提到过,我正在重复这个问题。但事情仍然对我不起作用。

标签: ios objective-c xcode xib


【解决方案1】:

我建议你改为这样做:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
        if([UIScreen mainScreen].bounds.size.height == 568.0)
        {
            //Use iPhone5 VC
            self = [super initWithNibName:@"RootViewController-568h" bundle:nibBundleOrNil];
        }
        else{
            //Use Default VC
            self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        }
    }
    return self;
}

如果你的 RootViewController 就是这样命名的。如果他们决定添加另一种尺寸的 iPhone/iPod,通过这种方式,您可以避免未来的崩溃。 当您使用两个 if 语句时,如果两者都不正确,则会导致应用程序崩溃,并且确实不是很好的编码。

一个好的做法是总是尝试提前思考并为未来做计划,如果他们应该发布另一个屏幕尺寸,它看起来不太好,但至少不会崩溃。

【讨论】:

    【解决方案2】:

    我从您的描述中看到的明显问题是您在 nib 中将自定义类设置为“RootViewController”,但实际上您在代码中实例化了“UIViewController”。

    你应该做的是:

    viewController3 = [[[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil] autorelease];
    

    否则,当运行时加载您的 nib 并尝试在您的 nib 中设置那些 RootViewController 特定的插座时,运行时将无法在普通 UIViewController 中找到这些插座,因此会崩溃。

    【讨论】:

    • 谢谢,但我忘了说我也试过了,但也没有用。
    【解决方案3】:

    我认为您不必为 iPhone5 和 iPhone4、4S 等使用两个不同的 .xib。如果您想更改图像、标签、按钮等的大小,这就是使用 Spring 和 Structs 的原因为了。您还可以使用您在问题中编写的代码(在您的 .m 文件中......)以编程方式设置大小

    我以前也犯过这个错误。以前运行程序的时候总是报错

    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
     reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "View" nib but
     the view outlet was not set.' *** First throw call stack:(0x1c93012 0x10d0e7e 0x1c92deb 
    0xf58c8 0xf5dc8 0xf5ff8 0xf6232 0x453d5 0x4576f 0x45905 0x4e917 0x2b7f 0x12157 0x12747 
    0x1394b 0x24cb5 0x25beb 0x17698 0x1beedf9 0x1beead0 0x1c08bf5 0x1c08962 0x1c39bb6 
    0x1c38f44 0x1c38e1b 0x1317a 0x14ffc 0x25fd 0x2525 0x1)libc++abi.dylib: 
    terminate called throwing an exception
    

    这是因为“笔尖出口没有设置”

    所以,我认为您应该使用 Springs 和 structs 或以编程方式执行..

    【讨论】:

    • 我也想过这样做.. 但对于我的应用程序,我认为这会很头疼。那就是我正在采用这种方法。
    【解决方案4】:

    我会推荐你​​:

    在实例化 VC 时使用故事板,而不是 XIB 文件,例如:

        myVC* vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myVCStoryBoardID"];
    
    [self.navigationController pushViewController:vc animated:YES];  
    

    这有助于将 VC 设计保持在同一屋檐下,并使用故事板的强大功能。

    然后检查故事板控制器上的自动布局是否处于活动状态,并确保一个(例如标签)上的约束映射到其他元素的边界(非常重要),上下。当您移动它时,这会通过蓝色虚线实现。在大多数情况下,无论屏幕高度如何,运行时都能对齐所有内容。

    我知道在这方面可能存在一些令人讨厌的边缘情况,因此您可能需要手动调整内容。除非您有复杂的图形,否则始终可以在 [0,1] 区间内使用 Y 坐标,并且一旦必须设置帧,请使用 [[UIScreen mainScreen] bounds].size 获取适当的值,四舍五入为最接近的整数。

    如果以上所有方法都失败了,那么您可能必须创建单独的 VC,但在我看来,这并不是 SDK 的真正用途。

    祝你好运!

    【讨论】:

      【解决方案5】:

      哇,我真是个傻瓜,我没有意识到我没有正确加载笔尖。唯一我错的是这行代码

      我写的 viewController3 = [[[UIViewController alloc] initWithNibName:@"RootViewController5" bundle:nil] autorelease]; 而不是

       [[NSBundle mainBundle] loadNibNamed:@"RootViewController5" owner:self options:nil];
      

      所以我的最终代码看起来像这样,并且工作得非常好

      if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
          {
              CGSize result = [[UIScreen mainScreen] bounds].size;
              if(result.height == 480)
              {
                  // iPhone Classic
                  [[NSBundle mainBundle] loadNibNamed:@"RootViewController" owner:self options:nil];
              }
              if(result.height == 568)
              {
                  // iPhone 5
                  [[NSBundle mainBundle] loadNibNamed:@"RootViewController5" owner:self options:nil];
              }
          }
      

      感谢此链接Link to the right Answer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-24
        • 2015-06-15
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多