Cocoa touch UIViewController未加载自定义UIView

Cocoa touch UIViewController未加载自定义UIView,cocoa-touch,Cocoa Touch,对于一个大师来说,这应该是直截了当的。我没有编写任何代码,只有几个控制器和一个自定义UIView。全部通过笔尖连接。应用程序加载时不会崩溃,但我无法从自定义UIView中看到我的NSLog()命中 我的应用程序委托具有默认模板代码,该代码调用我的一个名为TabAnimationController的类。TabAnimationViewController的视图设置为TabView。我确保在TabAnimationViewController的NIB中,文件的所有者设置为TabAnimationV

对于一个大师来说,这应该是直截了当的。我没有编写任何代码,只有几个控制器和一个自定义UIView。全部通过笔尖连接。应用程序加载时不会崩溃,但我无法从自定义UIView中看到我的NSLog()命中

我的应用程序委托具有默认模板代码,该代码调用我的一个名为TabAnimationController的类。TabAnimationViewController的视图设置为TabView。我确保在TabAnimationViewController的NIB中,文件的所有者设置为TabAnimationViewController,并且我的UIView实例的类设置为TabView

在TabView.m中,我正在尝试看看NSLog将如何发挥作用,但它根本没有出现

- (void)loadView {
 NSLog(@"calling loadView");
}

- (id)initWithFrame:(CGRect)frame {
NSLog(@"Calling initWithFrame:");
    return self;
}

奇怪。我不知道为什么即使在正确的IB连接之后,我的NSLog也不会显示。只有放入drawRect:中的任何内容才会调用。为什么initWithFrame或loadView从未被击中?如果要以编程方式自定义此视图,该怎么办?

首先,当从nib文件中提取视图时,将调用
initWithFrame
,而不是
initWithCoder
。因此,您还需要在
initWithCoder
中实现初始化。(如果您希望以编程方式创建选项卡视图,而不是连接到IB中,那么最好也保留
initWithFrame
初始化。只需将初始化重构为另一个方法,并从两个实现中调用它即可。)

此外,在上面的初始化代码中,必须始终调用超类的初始化。所有自定义类在其
init
实现中都使用锅炉板模式:

if (self = [super initXXX]) { do your initialization } 
return self;
其次,
loadView
它实际上是一个
UIViewController
方法,而不是
UIView
方法,只有当控制器的
view
出口为nil时才会被调用


除非您自己使用控制器以编程方式编写视图,否则不需要重写
loadView
。相反,您应该覆盖视图加载后调用的
viewDidLoad
,以进行额外的初始化。

建立并运行此功能的最简单方法是在创建新项目时使用“基于视图的应用程序”模板。它设置了您需要开始的所有内容

但是,简而言之,你看到的方法是错误的。首先,除非以编程方式创建视图,否则不应覆盖loadView。如果是从XIB文件加载,请查看initWithNibName方法


您可能还想查看触发的viewDidLoad、ViewWillExample和ViewDidExample方法,这在以下情况下非常明显

我想说你必须调用超级init,而不是应该。在上次的WWDC上有一首关于这一点的好歌:选择器名称错误。最后一段应该是,“相反,您应该覆盖viewDidLoad,…”