【问题标题】:Load view from xib in cocoa从可可中的xib加载视图
【发布时间】:2017-10-20 20:21:55
【问题描述】:

我正在尝试从我的可可应用程序中的 xib 文件加载视图(我使用情节提要)。

所以,我在故事板的 ViewController 中有 FirstView.xib 和一些名为“_contentView”的自定义视图。我执行以下操作:

NSArray *nibObjects;
[[NSBundle mainBundle] loadNibNamed:@"FirstView" owner:self topLevelObjects:&nibObjects];
[_contentView addSubview: nibObjects[1]];

..它可以工作,但有时我会收到以下错误:

-[NSApplication window]: unrecognized selector sent to instance 0xXXXXXXXXXXXX
Failed to set (contentViewController) user defined inspected property on (NSWindow): -[NSApplication window]: unrecognized selector sent to instance 0xXXXXXXXXXXXX

我做错了什么,如何解决?

【问题讨论】:

  • 搜索视图,不要假设视图是nibObjects[1]
  • 但是如何搜索视图呢?
  • 枚举nibObjects并检查类。
  • 谢谢,明白了!我必须检查 nibObjects[0] 和 nibObjects[1] 是否属于 NSView

标签: objective-c macos cocoa view xib


【解决方案1】:

不要看 nibObjects 数组。该数组仅用于保存 nib 中的所有顶级对象。 IE。所以你可以释放它,让它们全部消失。

相反,在您的类(您作为所有者传递的对象的类)中定义一个出口并将其连接到所需的视图。然后你可以加载笔尖并使用插座中的视图。这就是网点的用途。

更新:如果你有一个完整的列表或者想要加载同一个 XIB 的多个副本,创建例如每个 XIB 都有一个单独的 MYListItemViewController,并让 进行加载,然后让您当前的控制器创建 MYListItemViewControllers 并保留一个数组,而不是直接加载它们。

XIB 就是这样设计的。在同一个所有者上加载多个 XIB 不是一个好主意,您会收到多个 awakeFromNib 消息,其中一个,没有人预料到它,所以有人可能会添加一个插座,然后每次加载都会覆盖它。

【讨论】:

  • 在某些情况下,多个视图与多个所有者一起使用。
  • 这没什么区别。您创建一个拥有这些视图并拥有它们的出口的所有者类。您创建此所有者的一个实例,然后让您的当前控制器保留一组此类所有者并与这些所有者交谈,而不是直接搞砸。这就是 XIB 的工作原理。在同一个所有者上加载多个 XIB 不是一个好主意,你会收到多个 awakeFromNib 消息,其中一个,没有人预料到它,所以有人可能会添加一个插座,然后每次加载都会覆盖它。
  • 我是否理解正确:为每个 nib(一个简单的附件视图)创建一个 nib 所有者类,实例化以加载 nib,获取视图并让 ARC 释放所有者?不要指望awakeFromNib 只会被调用一次。
  • 差不多。您保留所有者,并将需要直接了解 nib 中对象的任何代码放入该所有者。此所有者之外的其他代码只是获得一个容器视图以放置到其他内容中。就像 NSViewController 一样。这也将更容易拥有 nib 的变体,或更改 Nib 的实际布局,而无需更新所有其他代码。
【解决方案2】:

所以,感谢@Willeke。解决办法是:

NSArray *nibObjects = [[NSArray alloc] init];
[[NSBundle bundleForClass:[self class]] loadNibNamed:subViewName owner:self topLevelObjects:&nibObjects];
    if ([nibObjects[1] isKindOfClass:[NSView class]]){
        [_customView setSubviews:[NSArray array]];
        [_customView addSubview: nibObjects[1]];
    }
    else {
        [_customView setSubviews:[NSArray array]];
        [_customView addSubview: nibObjects[0]];
    }

【讨论】:

  • nibObjects[2]nibObjects[3] 怎么样?这是答案:programmatically loading object from subclass of NSView from nib
  • 但数组的大小始终为 1
  • 或者代替 NSArray *nibObjects = [[NSArray alloc] init] 我们可以使用 NSMutableArray *nibObjects = [NSMutableArray arrayWithCapacity:1]
  • 如果数组大小一直为1,nibObjects[1]会崩溃。您不必实例化数组,loadNibNamed 会这样做。您的[[NSArray alloc] init] 将被丢弃。
猜你喜欢
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 2015-05-21
  • 2012-12-28
  • 1970-01-01
  • 2019-07-04
相关资源
最近更新 更多