使用情节提要的自定义视图


96

在复杂的屏幕(视图控制器)中,我通常将整个事情分成较小的部分(我称它们为小部件)。这些小部件基本上由a MyWidget.h和一个MyWidget.m文件以及一个MyWidget.xib文件组成,其中根元素是a UIView,而MyWidget类是UIView的文件所有者。在此小部件的初始化中,我做了一个loadNibNamed

然后在View Controller中执行一个[[MyWidget alloc] init],将其作为子视图添加到View的Controller主视图中。到目前为止,这是完美的。

我现在想知道如何对情节提要进行相同的操作,因为我无法真正开始将其拖到UIView某个地方,所以我总是必须以UIViewController不想开始。

如果无法使用情节提要板执行此操作,是否可以通过将情节提要板用于主屏幕和剧集,并使用单独的.xib文件来定义自定义视图,以旧的方式进行操作?


是否要xib为视图控制器单独创建,而不是在故事板上创建s?
tipycalFlow

您找到解决方案了吗?
aryaxt 2012年

@aryaxt:我使用的是Storyboard和xib。用于主屏幕的故事板和仅将UIView作为复杂视图或小部件的根的xib。因此,这并不是我最初的问题的答案(使用情节提要),但基本上可以完成之前的工作。
znq 2012年

这些天,只使用一个容器视图,它就是这么简单.. stackoverflow.com/questions/23399061/...
Fattie

Answers:


189

将小部件/视图放置在单独的.xib文件中是可行的,并且特别适用于您可能希望从多个视图控制器引用同一视图的情况。

但是,有时您确实希望在同一情节提要中看到其他视图/小部件,并且有可能。这是您的操作方式:

  1. 在IB中选择视图控制器(单击视图下方的黑条),然后将UIView从对象库拖到黑条中:

    在此处输入图片说明

  2. 当视图在黑色栏中时,它像IB中的任何其他视图一样被实例化,但是直到您在代码中将其添加到视图层次结构中为止。如有必要,更改视图的类以匹配您自己的子类:

    在此处输入图片说明

  3. 您可以将其连接到视图控制器,就像连接其他任何视图一样: 在此处输入图片说明

  4. 添加的视图显示在“文档大纲”中,您也可以在此处挂接操作和引用:

    在此处输入图片说明


现在,仍然存在的问题是,无论您尝试单击或双击多少次,您实际上都无法看到视图,这将使将其放置在同一情节提要中的整个目的无法实现。幸运的是,我知道有两种解决方法。

第一种解决方法是将视图从黑条拖回视图控制器的视图,进行编辑,然后在完成后将其拖回黑条。这是麻烦的但可靠的。

另一个解决方法比较挑剔,但我更喜欢它,因为它可以让我同时查看所有视图:

  1. 将UITableView从对象库拖到新添加的视图中。

  2. 然后将一个UITableViewCell拖到该UITableView中。

    在此处输入图片说明

  3. 完成此操作后,您的视图会以魔术般的方式弹出,但是您有一个不需要的UITableView。您可以将其大小调整为0x0,也可以删除它,并且UIView(通常)仍将保持可见状态。

  4. 有时,辅助视图将再次在IB​​中隐藏。如果删除了UITableView,或者如果UITableView仍在层次结构中,则只需重复单击UITableViewCell,即可重复上述步骤。

第二种方法适用于UIView,但不适用于UIToolbars,也不适用于UIButton,因此,当您需要包含许多不同的子视图时,我发现的最干净的解决方案是将单个辅助UIView作为容器附加到视图控制器。永不显示,将所有辅助视图放在此处,并使用UITableViewCell技巧使所有内容可见。我将虚拟UITableView的大小调整为0x0,以使其不可见。这是所有内容的屏幕截图:

在此处输入图片说明


2013年3月,我不需要这样做-您应该完全忽略黑条,然后将视图直接拖放到主视图中,并且可以正常工作(Xcode 4.5+)
亚当

是否可以在同一ViewController上重用该自定义uivew-如果我是ex。需要两个自定义的ivev-如果是这样的话?
Morten Gustafsson

2
邓,我更喜欢只创建一个单独的xib。当我必须在6个月内更新应用程序时,我可能不会记住所有这些信息。
桑迪,

尽管这是一个很棒的答案,但我偶然发现了另一种更好的思考方式。将插座连接到实际视图组件时。如果将鼠标悬停在这种内部视图的某个组件上,它会弹出以方便选择。然后在情节
提要

7
尽管这是一个令人难以置信的令人钦佩的历史答案,但实际上,它现在已经完全过时了。苹果通过引入“容器视图”解决了整个问题,现在这是制作应用程序时要做的核心,基本的事情-始终将所有内容都作为“容器视图”。谢天谢地,现在非常简单!
Fattie

11

如果您只是想将视图控制器放在其他位置(而不是放在故事板中),那么有一种非常简单的方法可以完成此操作:

1)像往常一样用他们的个人s 创建您的CustomViewControllers(abcdController在我尝试的代码中)xib

2)在故事板上添加一个UIViewController(或您的超类CustomViewController)。

3)将CustomClass设置为,CustomViewController而不是UIViewController如下所示:

在此处输入图片说明

4)最后,在您的中viewDidLoad,加载自定义设置xib,您就完成了。

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSBundle mainBundle] loadNibNamed:@"abcdController" owner:self options:nil];
    // Do any additional setup after loading the view from its nib.
}

3
感谢您提供非常详细的答案,但实际上我不是在寻找自定义视图控制器,而是自定义视图(窗口小部件),该视图已添加到标准UIViewController中。因此,视图控制器不是问题,但我想知道最好的方法是创建自定义窗口小部件。A)像以前一样使用.xib文件来完成此操作,或者B)我不知道的其他方法:-)
znq 2012年

1
嗯...我想我得到了你想要的。基本上,您想使用同一控制器处理多个视图,对吗?我想不出比其他的方式loadNibNamed在这种情况下... XO
tipycalFlow

这为我解决了这个问题:stackoverflow.com/questions/11047991/… 但是,我不是使用viewDidLoad,而是使用loadView ...
Morkrom 2013年

1
只是重复一遍,既然容器视图在这里,这就是所有(谢谢天哪!)完全过时了。只需单击容器视图即可完成
Fattie 2014年

1

我认为您可以执行以下操作从Storyboard获取特定ViewController的实例,并在其顶部使用View。

ex:
MyViewController* myViewController = [[UIStoryboard storyboardWithName:@"Main"  bundle:nil] instantiateViewControllerWithIdentifier:@"myViewController"];
UIView* view = myViewController.view; //Get the view from your StoryBoard.

希望这可以帮助

谢谢维杰

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.