创建一个没有nib文件的视图控制器

4
在AppDelegate中,我想要创建一个UIViewController子类并添加它的视图。视图本身将在代码中指定-没有nib。
根据Apple文档,我应该使用:
initWithNibName:nil bundle:nil];

在控制器的loadView中,我添加了子视图等内容。
然而,以下测试代码对我无效。 我的AppDelegate代码是基于苹果公司的PageControl演示模型的{{link1:PageControl demo}},因为我的应用程序将实现类似的结构(特别是一个基本控制器来管理分页滚动视图和其他控制器的数组来构建页面)。
但我怀疑我的AppDelegate代码有问题,因为日志证明initWithNibName ::和loadView都会触发。 以下应用程序运行,但屏幕是空白的。 我期望看到一个带标签的绿色视图。 AppDelegate
        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        ScrollerController *controller = [[ScrollerController alloc] initWithNibName:nil bundle:nil];
        [self.window addSubview:controller.view];
        [self.window makeKeyAndVisible];
        return YES;
    }

ScrollerController(UIViewController子类)

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)loadView{
    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
    UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame];
    contentView.backgroundColor = [UIColor greenColor];
    self.view = contentView;

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(40, 40, 100, 40)];
    [label setText:@"Label created in ScrollerController.loadView"];
    [self.view addSubview:label];
}

我在演示项目中注意到有一个xib文件,其中AppDelegate作为文件所有者 - 大概是为了提供我所缺少的部分给应用程序? - Ben Packard
在viewDidLoad之后检查你的视图包含了什么。 - Sulthan
似乎一切都在那里 - self.view: <UIView: 0x6e0f630; frame = (0 20; 320 460); layer = <CALayer: 0x6e0fbc0>> 子视图:1 子视图0:<UILabel: 0x6e10d80; frame = (40 40; 100 40); text = 'Label created in Scroller...'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x6e0fd80>> - Ben Packard
2个回答

5
尝试使用以下代码: self.window.rootViewController = controller; 而不是 [self.window addSubview:controller.view]; 请注意,您还应该使用@synthesize window;并创建它: self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

我正在合成窗口,但为什么我需要自己创建它呢?我只是问一下,因为苹果的演示项目没有这样做。 - Ben Packard
这取决于你是完全通过编程创建所有内容,还是使用nib中的窗口。如果你没有使用nib中的窗口,那么你需要像Sulthan建议的那样通过编程创建窗口。 - timthetoolman

4

使用alloc和init或任何其他视图控制器的指定初始化程序,而不是initWithNibNamed:。以下是来自一个项目的示例:

项目
hoverViewController=[[BDHoverViewController alloc] initWithHoverStatusStyle:BDHoverViewStatusActivityProgressStyle];
self.window.rootViewController=hoverViewController;
[self.window makeKeyAndVisible];

此外,目前(至少)将根视图控制器添加到应用程序委托中的正确方式如下:

self.window.rootViewcontroller=controller;
[self.window makeKeyAndVisible];

您不需要将视图添加到窗口中。上面的代码会自动完成这一步骤。
祝好运,
T

这段代码的后半部分看起来不错,但是你有第一部分的任何来源吗?我之所以问是因为我曾经阅读过(我想是在苹果文档中)正确初始化一个没有nib的控制器的方法是使用nil。我会看看我能否找到我阅读过的地方。 - Ben Packard
我在Stack Overflow上读到了这篇文章,所以不一定是权威的:2a. 编程方式加载视图如果你选择重写-loadView方法,你可以创建视图、子视图、其他视图控制器以及这些对象之间的任何连接,以任何你想要的方式。当然,这意味着你也需要对你创建的对象进行内存管理。如果你的子类重写了-loadView方法,则应该将nibName和bundle都初始化为nil。来源:https://dev59.com/cW435IYBdhLWcg3w-lP2 - Ben Packard
1
是的,你说得对,我快速查看了文档,那是正确的。为了安全起见,如果我在使用方法,则尝试仅使用initWithNibNamed:方法。我已经更新了我的答案。 - timthetoolman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接