ios - 在情节提要中加载 xib 视图。为什么我们必须做 self.addSubview(nibView) ?
问题描述
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
self.addSubview(view) // My question
}
func loadViewFromNib() -> UIView? {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: self.className, bundle: bundle)
return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
我希望 customXibView 以 nib 为初始值。看起来像 self = loadViewFromNib(),而不是 self.addSubview(nibView)。
发现很多答案都是self.addSubview(nibView)做的。实际上,查看我们的视图层次结构,我们会发现一个额外的视图。 这是我的视图层次结构
有没有办法将 xib 实例化到情节提要,而不是通过 self.addSubview(nibView)。
如果您不理解我的问题,请查看Xib 中的这个自定义 UIView - 要求,良好做法。我希望有人能帮助我。
解决方案
有以下三种情况:
您有一个
CustomView
类,其所有 UI 都在其 drawRect 方法中以编程方式定义。您有
CustomView
一个类,其 UI 在情节提要场景的子视图中定义,其类设置为“CustomView
”。您有
CustomView
一个类,其 UI 在单独的 xib 中定义。
现在,如果您想将您的 CustomView 作为子视图包含在您的视图控制器中,则该方法会有所不同,具体取决于您的类在第一个实例中的定义方式。其次,您希望如何将其包含在您的视图控制器中。
使用场景 1 添加 CustomView:
在 viewDidLoad 方法中初始化 CustomView 实例,并将其作为子视图添加到 viewcontroller 的视图中。
添加具有条件 2 的 CustomView:
在这种情况下,您无需执行任何操作。故事板将为您初始化您的课程。您可以在初始化视图时调用的 init(coder) 方法中进行额外的设置。
添加具有条件 3 的 CustomView:
使用 xib 初始化视图的正确方法是通过 UINib 的inistantiateWithOwner
方法以编程方式对其进行初始化。viewDidLoad
然后在视图控制器的方法中将视图添加为子视图。
您正在做什么(或者我可以猜到您的图像层次结构)是您已将您的类更改为UIView
您的自定义类。现在,由于您有一个单独的 xib,因此您正在init(coder)
方法中对其进行初始化,并将其作为子视图添加到在情节提要中定义和初始化的视图中。因此,您最终会得到一个额外的容器视图。
如果您不想要额外的视图,请以编程方式添加您的自定义视图。
或者
(如果可能)复制在 xib 中定义的视图并将其放置在 viewcontroller 扩展坞中,然后将视图与插座链接并将其添加到viewDidLoad
方法中。
推荐阅读
- javascript - 从 DataTable JSON 中提取数字字符并添加间距
- python - 为什么我会收到此错误?'_io.TextIOWrapper' 对象没有属性 'append'
- c++ - 如果为 false,std::is_member_function_pointer 不会编译
- c# - Microsoft.AspNetCore.App - 版本控制/是否应该在非 ASP.NET 类库中引用?
- php - phpcs 一直扫描整个项目而不是指定目录
- jquery - Laravel5.8 jQuery发布请求说它是一个获取路线
- konvajs - Konva JS - 带有图像的工具提示
- angular - 如果 TS 文件中的导入不是相关路径,则为移动中断构建 Nativescript
- c# - 在 Web API 中设置 ZipArchive Zip 文件的名称
- excel - 如何在 MS Excel 中制作动画形状