cocoa - 不一致的视图层次结构
问题描述
我尝试将基于 .xib 的自定义视图添加到另一个基于 .xib 的自定义视图中。结果如下所示:
for sub in v.subviews {
Swift.print(v.subviews) // returns array [sub]
Swift.print(sub) // returns sub
Swift.print(sub.superview) // return nil!
}
一个视图怎么可能在superview的子视图中,但是superview属性没有正确设置?这会在解码/编码期间发生吗?我需要设置什么才能使其正确?
下一个问题是,为什么sub
在“查看调试”中正确显示,但在运行时需要它时却没有。
编辑:(感谢马特对此进行调查)我的代码如下所示:
import AppKit
func showXIBDefinedInPanel(name: String, title: String ) {
if let w = loadXIBDefined(name: name) {
let c = NSViewController()
c.view = w
let window = NSPanel(contentViewController: c)
window.isMovable = true
window.collectionBehavior = .canJoinAllSpaces
window.tabbingMode = .disallowed
window.title = title
window.styleMask = [ .titled, .utilityWindow, .closable]
window.makeKeyAndOrderFront(w)
}
}
func loadXIBDefined(name: String) -> XIBDefined? {
var topLevelObjects : NSArray?
var result : XIBDefined? = nil
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: name), owner: nil, topLevelObjects: &topLevelObjects) {
result = topLevelObjects!.first(where: { $0 is XIBDefined }) as? XIBDefined
}
return result
}
///used to embed a XIBDefined into another XIB
@IBDesignable class XIBEmbedder : NSView {
// Our custom view from the XIB file
var view: NSView!
var xibName: String!
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
view = loadXIBDefined(name: xibName)
addSubview(view)
self.frame = view.frame
}
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
view = loadXIBDefined(name: xibName)
addSubview(view)
self.frame = view.frame
}
init(name: String) {
self.xibName = name
super.init(frame: NSZeroRect)
view = loadXIBDefined(name: xibName)
addSubview(view)
self.frame = view.frame
}
}
///used as class for XIB based Custom Views
@IBDesignable class XIBDefined: NSView {
///I had an issue with an oddly moved frame, so I hard coded a fix
override func setFrameOrigin(_ newOrigin: NSPoint) {
super.setFrameOrigin(NSZeroPoint)
needsDisplay = true
}
}
@IBDesignable class WelcomeCMapView : XIBEmbedder {
init() {
super.init(name: "Welcome Concept Maps")
}
required init?(coder decoder: NSCoder) {
super.init(name: "Welcome Concept Maps")
}
}
关键是两个类XIBDefined
和XIBEmbedder
。前者可以从 XIB 加载,后者可以在 XIB 中使用。所以后来的嵌入式XIB作为自定义类使用XIBDefined
,嵌入XIB有一个WelcomeCMapView
as custom class。
顶部的问题显示代码是后处理的一部分,viewDidLoad()
在NSViewController
加载嵌入 XIB 后执行。
解决方案
推荐阅读
- html - 悬停asp.net网站上的下拉菜单消失
- javascript - Highcharts:删除标记附带的图例符号
- optimization - 解决 NP 难题的大 O 复杂度
- python - 在子文件夹中导入 python 函数
- java - 如何从控制台获得正确的输出
- flutter - 如何在颤动中为背景图像设置动画
- c++ - 为什么我的代码不适用于大于 12 的输入?
- python - BLE 嗅探:来自 adb bugreport 的 btsnoop 日志使用 python 脚本 - 编码/解码问题
- ansible - 错误!“注册”不是 Play 的有效属性
- npm - npm: git 认证安装包