当前位置: 首页 > 面试题库 >

在Swift中从笔尖加载UIView

邓昀
2023-03-14
问题内容

这是我的Objective-C代码,我正在使用该代码为我的自定义加载笔尖UIView

-(id)init{

    NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"myXib" owner:self options:nil];
    return [subviewArray objectAtIndex:0];

}

Swift中的等效代码是什么?


问题答案:

原始解决方案

  1. 我创建了一个XIB和一个名为SomeView的类(为方便起见,使用了相同的名称)。我都基于UIView。
  2. 在XIB中,我将“文件所有者”类更改为SomeView(在身份检查器中)。
  3. 我在SomeView.swift中创建了一个UIView出口,将其链接到XIB文件中的顶级视图(为方便起见,将其命名为“视图”)。然后,根据需要将其他插座添加到XIB文件中的其他控件
  4. 在SomeView.swift中,我将XIB加载到“使用代码初始化”初始化程序中。无需为“自己”分配任何内容。加载XIB后,所有插座都将连接,包括顶层视图。唯一缺少的是将顶视图添加到视图层次结构中:

class SomeView: UIView {
   required init(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
      NSBundle.mainBundle().loadNibNamed("SomeView", owner: self, options: nil)
      self.addSubview(self.view);    // adding the top level view to the view hierarchy
   }
   ...
}

请注意,通过这种方式,我得到了一个从笔尖加载自身的类。然后,只要可以在项目中使用UIView(在界面生成器中或以编程方式),就可以将SomeView用作类。

更新-使用Swift 3语法

在以下扩展中加载xib是作为一种实例方法编写的,然后可以由上面的初始化程序使用:

extension UIView {

    @discardableResult   // 1
    func fromNib<T : UIView>() -> T? {   // 2
        guard let contentView = Bundle(for: type(of: self)).loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)?.first as? T else {    // 3
            // xib not loaded, or its top view is of the wrong type
            return nil
        }
        self.addSubview(contentView)     // 4
        contentView.translatesAutoresizingMaskIntoConstraints = false   // 5 
        contentView.layoutAttachAll(to: self)   // 6 
        return contentView   // 7
    }
}
  1. 使用可丢弃的返回值,因为当所有插座都已连接时,调用者对返回的视图几乎没有兴趣。
  2. 这是一个通用方法,它返回类型为UIView的可选对象。如果无法加载视图,则返回nil。
  3. 尝试以与当前类实例相同的名称加载XIB文件。如果失败,则返回nil。
  4. 将顶级视图添加到视图层次结构。
  5. 此行假定我们正在使用约束来布局视图。
  6. 此方法增加了顶部,底部,前导和尾随约束-将视图在所有侧面附加到“自身”
  7. 返回顶层视图

调用方方法可能如下所示:

final class SomeView: UIView {   // 1.
   required init?(coder aDecoder: NSCoder) {   // 2 - storyboard initializer
      super.init(coder: aDecoder)
      fromNib()   // 5.
   }
   init() {   // 3 - programmatic initializer
      super.init(frame: CGRect.zero)  // 4.
      fromNib()  // 6.
   }
   // other methods ...
}
  1. SomeClass是一个UIView子类,可从SomeClass.xib文件加载其内容。“最终”关键字是可选的。
  2. 用于在情节提要中使用视图的初始化程序(请记住,将SomeClass用作情节提要视图的自定义类)。
  3. 用于以编程方式创建视图时的初始化程序(即:“ let myView = SomeView()”)。
  4. 使用全零帧,因为此视图是使用自动布局进行布局的。请注意,“ init(frame:CGRect){..}”方法不是独立创建的,因为自动布局仅在我们的项目中使用。
  5. &6.使用扩展名加载xib文件。

信用:在此解决方案中使用通用扩展名的灵感来自以下罗伯特的回答。

编辑 将“视图”更改为“ contentView”以避免混淆。还将数组下标更改为“ .first”。



 类似资料:
  • 问题内容: 我想从我的应用程序中的URL加载图像,因此我首先尝试使用Objective-C,但是它可以正常工作,但是对于Swift,我遇到了编译错误: ‘imageWithData’不可用:使用对象构造’UIImage(data :)’ 我的功能: 在Objective-C中: 有人可以解释一下为什么Swift无法使用它,以及如何解决该问题。 问题答案: Xcode 8或更高版本•Swift 3或

  • 我想从我的应用程序中的URL加载一个图像,所以我首先尝试使用Objective-C,它成功了,但是,使用Swift,我有一个编译错误: “imageWithData”不可用:使用对象构造“UIImage(数据:)” 我的职能: 在目标C中: 有人能给我解释一下为什么不能与Swift一起工作,以及我如何解决这个问题。

  • 问题内容: 我有一些类似的HTML 在Angular加载之前,我是否可以隐藏?所以它只会说 我似乎有一些解决方案,例如在Angular加载之前将整个身体隐藏起来,但我宁愿不要这样做。 问题答案: 是的,请使用ng- cloak 。只需添加或添加到这样的元素 使用指令 使用类 这只是一组CSS规则,并且随着Angular渲染DOM,它会删除ng-cloak,因此可见一个元素。

  • 问题内容: 我有以下代码: 我收到以下错误: “ NSURLRequest”不可转换为UIWebView。 知道是什么问题吗? 问题答案: loadRequest:是实例方法,不是类方法。您应该尝试使用UIWebview的实例作为接收者而不是类本身来调用此方法。 但是,正如@radex在下面正确指出的那样,您还可以利用currying来调用如下函数: 斯威夫特5

  • 问题内容: 我有一个用代码创建的(没有): 在另一堂课中,我有一个扩展方法来下载图像异步: 我在其他地方使用了此功能并正常工作,根据我的日志,我了解到下载的图像没有问题(渲染单元时),下载图像后,单元UI未更新。 我也尝试使用像Haneke这样的缓存库,但是问题存在并且没有改变。 请帮助我理解错误 谢谢 问题答案: 设置图像后,您应该致电 编辑:从改正为

  • 问题内容: 我已经阅读了使用XCode故事板来实例化使用XIB进行设计的视图控制器,但是在Swift中使用XCode进行工作时遇到了麻烦(使用Xcode 6 Beta 6)。我想知道我做错了什么还是该功能不再可用? 我创建了一个简单的存储库https://github.com/jer-k/StoryboardTesting- Swift ,展示了上述方法。 我设法通过在init中添加和覆盖来解决此