nib 中的 UIView 在 iPad 上是 nil,在 iPhone 上不是 nil
Posted
技术标签:
【中文标题】nib 中的 UIView 在 iPad 上是 nil,在 iPhone 上不是 nil【英文标题】:UIView in nib is nil on iPad, and not nil on iPhone 【发布时间】:2013-02-20 22:13:38 【问题描述】:我的应用有一个奇怪的问题。我在运行时使用名为“LoginViewController”的 NIB 加载 VC。该NIB 有一堆UIView
对象的出口,这些对象放置在NIB 中,如下所示:
在运行时,我将这些 UIView 对象作为标题动态放置在我的表格视图中。在这种情况下,每个单独的UIView
(除了右侧的UITableView
除外)都设置为像这样的IBOutlet。当然,每个都有不同的名称:
@property (strong, nonatomic) IBOutlet UIView *connectionInProgressView;
现在,在我的 VC 的 viewDidLoad
方法中,我运行了所有这四个单独的视图,并通过写入日志来确保它们存在:
NSLog(@"connection in progress view: %@", self.connectionInProgressView);
我的问题是:self.connectionInProgressView
在 iPad 上是 nil 而在 iPhone 上不是 nil。无论平台如何,所有其他视图都不是 nil 并且被实例化。我在 ios 5.0、5.1 和 6.1 的模拟器中运行它。我可以在所有 iPad 模拟器上重现该问题。我的应用程序运行良好,并在 iPhone 上使用微调器加载视图,但在 iPad 上它无法加载该视图,因为它是零!为什么!?
我尝试了以下方法:
检查我的 NIB 的文件所有者是否指向正确的视图self.connectionInProgressView
不指向任何其他 IBOutlet
检查所有其他子视图是否以与违规视图相同的方式连接。他们是。
删除 self.connectionInProgressView
并在删除其所有 NIB 连接后重新创建它。
从视图中删除活动指示器并仅加载内部带有UILabel
的视图。不走运,它不是活动指示器。
检查了 VC 中可能引用self.connectionInProgressView
的任何代码。没有(除了viewDidUnLoad
中的 nil 声明)。
检查UINavigationController
和LoginViewController
的AppDelegate 属性的属性类型。
在 AppDelegate 上保留 LoginViewController
的副本,尽管这似乎很浪费,并且对结果没有任何影响。
[编辑 2]
问题:VC是如何加载的
我有一个UINavigationController
,它是我的 AppDelegate 上的一个属性。 UINavigationController
是在 applicationDidFinishLaunchingWithOptions
中分配初始化的,我将我的 VC 作为根视图控制器传递给它。此时我将 VC 实例化。
// Create login/start up views
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
self.loginViewNavigationController = [[UINavigationController alloc] initWithRootViewController:loginViewController];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
self.loginViewNavigationController.modalPresentationStyle = UIModalPresentationFormSheet;
请注意,这在 iPhone 上有效,尽管我稍后会在 iPad 上将此 UINavigationController
显示为模式表单(不确定这是否会导致我的问题)。
稍后在 AppDelegate 中,当一个不同的委托类抛出一个事件时,我将展示这个 UINavigationController,我的 VC 以模态方式包含在其中。我是这样做的:
if (self.loginViewNavigationController != nil)
[self.window.rootViewController presentViewController:self.loginViewNavigationController animated:YES completion:nil];
我正在发疯,试图确定为什么这个特定视图拖到我的 NIB 上并与所有其他视图一样连接起来,在 iPad 上是 nil 而在 iPhone 上不是 nil。
[编辑 1] 在搜索重复的问题时,我没有找到这个:
A few IBOutlets pointing to nil
我并不孤单!
有什么想法吗?
【问题讨论】:
您对 iPhone 和 iPad 有单独的目标吗?如果是这样,这个笔尖是否针对两者?您是否仅使用此笔尖遇到此问题(不在 iPad 上工作)?还是在所有笔尖上都有? 不,我正在构建一个通用二进制文件。 NIB 只针对一个目标。我只是在这个特定的 NIB 上遇到了这个问题。 viewDidUnload 永远不会被调用。摆脱它。 请显示实际导致 nib 加载的代码 - 它只是一些 UIViewController 的实例化吗? 【参考方案1】:在构建通用应用程序时,您确定没有为 iPhone 和 iPad 创建单独的 NIB(通常为LoginViewController.xib
和 LoginViewController~ipad.xib
)?
或者您可能认为您只有一个 XIB,但在某些时候您有一个专用于 iPad 的 XIB,它被编译成一个 NIB,即使您在项目中删除了 XIB 文件,编译后的 iPad 专用 XIB 仍然存在构建产品。
无论如何,请尝试:
清理您的项目,甚至更好地清理您的构建产品目录 要执行后者,您可以删除派生数据文件夹(“组织器”窗口 -> “项目”选项卡 -> 在左侧选择您的项目 -> 单击“派生数据”旁边的“删除”按钮) 从所有模拟器中删除您的应用,以确保安全 再次构建并运行如果这不起作用,一些想法可以帮助您调试并确定问题是否与使用不同 XIB 的 iPad 有关:
您可以尝试一些测试,例如修改您的 XIB 的另一个IBOutlet
,例如将不是 nil
的其他 IBOutlet
之一从它在 XIB 中连接到的视图中断开,这样当您运行您的应用程序再次应该记录为nil
。如果在 iPhone 模拟器上是 nil
(正如预期的那样,你刚刚断开了它)......但在 iPad 模拟器上仍然不是nil
,那么这肯定意味着你为 iPhone 和 iPad 使用了不同的 XIB 文件。
您还可以在 XIB 中更改您的 UIView
的颜色,该颜色已正确连接到您的 IBOutlet
之一,并查看更改是否反映在 iPhone 和 iPad 或仅在 iPhone 上,所以检查您正在编辑的这个 XIB 是否与 iPad 中使用的相同。
【讨论】:
阿里 - 我会仔细阅读你的建议。为了回答你的第一个问题,我有一个完全独立的表格单元格大小问题,我认为我可以通过连接 ~ipad.xib 来解决。我试过了,它没有用,然后我删除了~ipad.xib。从那以后,我已经多次清理了这个项目,但都无济于事。 您是否也重置了模拟器? @Rog - 重置模拟器是什么意思。我对 iOS 开发还比较陌生,所以我可能会遗漏一些明显的东西。 @Ali - 上面的步骤 1-3 解决了我的问题。我删除了构建产品目录,从每个模拟器中删除了应用程序,瞧,幽灵 .xib 问题已解决。 干得好。这吸引了很多人,包括有经验的 Xcode 用户:构建应用程序不会从以前的构建中删除应用程序中的内容,所以你真的不知道里面有什么。唯一的出路是清理一切。在这里比较我的答案:***.com/a/6247073/341994【参考方案2】:我遇到了类似的问题,清理了我的项目,删除了派生数据,确保我没有为 iPad 使用单独的 xib;似乎没有任何效果。原来我的问题非常简单。我像这样初始化我的视图控制器:
// In Swift
let vc = MyViewController()
而不是直接使用 nibName:
let vc = MyViewController(nibName: "MyViewController", bundle: NSBundle.mainBundle())
由于我的 nil-outlet 错误似乎只在 iPad 上测试时出现,所以我从未想过要检查控制器是如何初始化的。
【讨论】:
【参考方案3】:对于这个特定的案例,我遇到了一件奇怪的事情。我让UITextField
成为viewDidLoad
的第一响应者,我让NSNotifications
连接到UITextField
来管理键盘框架等。但有趣的是,当通知在viewDidLoad
中发送时,仅在iPad 上,网点为零(与 iPhone 不同)。很奇怪。
【讨论】:
以上是关于nib 中的 UIView 在 iPad 上是 nil,在 iPhone 上不是 nil的主要内容,如果未能解决你的问题,请参考以下文章
nib loader 只保留 nib 中的第一个*** UIView?
如何从 ViewController 中的 xib (nib) 实例化 UIView / UITableView