【问题标题】:Swift: Load XIB when instantiating viewcontrollerSwift:实例化视图控制器时加载 XIB
【发布时间】:2015-03-24 10:35:41
【问题描述】:

我最近将我的项目升级到了 Swift,我试图弄清楚如何动态地实例化我的 XIB,同时保持对我的视图控制器的强引用。我讨厌打电话给NSBundle.mainBundle().loadNibNamed("someXib"),因为你的视图控制器有一个字符串表示可能会使它容易出现拼写错误,很难记住每个 XIB 的名称,并且如果我选择重命名 XIB 非常困难。

在 Objective-c 中,我会简单地实例化视图控制器并像这样推送它:

CRMyViewController *myVC = [CRMyViewController new];
[self.navigationController presentViewController:myVC animated:YES completion:nil];

这允许我强烈引用我的视图控制器(及其关联的 XIB),如果我拼写错误或重命名了我的视图控制器,我的项目将根本无法编译。

当我尝试引用 Swift-XIB 的这种方法时,我的视图从未加载。但是,我可以通过简单地在我的视图控制器中覆盖 loadView 来接近我想要的:

override func loadView() {              
    NSBundle.mainBundle().loadNibNamed("CRMyViewController", owner:self, options:nil) 
}

这与我想要的很接近,因为我只对 xib 名称进行了一次硬编码(并且在实际的视图控制器中),但我仍然更喜欢更动态的方法。

有没有办法动态加载 Swift-XIB 和视图控制器?我唯一能想到的就是创建自己的基本视图控制器并以更动态的方式覆盖 loadView:

override func loadView() {        
    var className:NSString = NSStringFromClass(self.classForCoder)
    className = className.componentsSeparatedByString(".").last as NSString
    NSBundle.mainBundle().loadNibNamed(className, owner:self, options:nil)
}

有没有更好的方法来加载 XIB 和视图控制器?为什么这在 Swift 中是必要的而不是在 Objective-c 中?

【问题讨论】:

  • 我不太明白你问题的第一部分。在 Objective C 中实例化一个新的视图控制器也不应该加载你的 nib,除非视图控制器在自身内部的代码中加载了 nib。在 Swift 中应该没有什么不同。在没有指定 nib 名称的情况下,Objective C 中无法加载 nib,就像在 Swift 中一样。
  • 这就是我每次在objective-c中的做法。我所做的只是实例化 viewcontroller 并呈现它,我的 xib/view 也随之加载。我不需要像上面的 swift 代码那样做任何花哨的事情。
  • 看来我错了。 nib 文档提到了视图控制器和相关 nib 的链接。我以前从来没有这样用过。看起来很脆弱。我会尝试深入挖掘,看看发生了什么。
  • 我最初的想法是,因为 Swift 类名与 Objective C 中的不同,_loadViewFromNibNamed 将不起作用。稍后我会尝试输入更多详细信息。

标签: ios swift uiviewcontroller xib


【解决方案1】:

您可以通过在@objc 块中指定类来指定类的名称:

@objc(CRMyViewController) class CRMyViewController: UIViewController {

}

这应该可以解决 _loadViewFromNibNamed:bundle: 使用错误名称的问题。

你可以在这里找到更多关于类名如何在 Swift 中工作的信息:Get class name of object as string in Swift

【讨论】:

  • 你说得对,这行得通!所以你认为问题是迅速取错名字?不过老实说,我不确定您的解决方案是否比我的 baseviewcontroller 覆盖 loadview 更好。我宁愿不必记住用@objc 包装每个类。从我可以继续扩展的现有 baseviewcontroller 继承要容易得多。 +1 有效的答案。 -1 快速愚蠢
  • @Oren 这样做的好处是任何其他依赖类名的私有 API 都可以工作。在您对. 进行拆分的解决方案中,您依赖于类名字符串的特定实现,即使这不太可能改变,但它可以并且您可能不会收到任何警告。
  • 为什么 xcode 不默认添加它?是否有任何伤害/影响?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多