Cocoa 不一致的视图层次结构
我尝试将基于.xib的自定义视图添加到另一个基于.xib的自定义视图中。 结果如下所示:Cocoa 不一致的视图层次结构,cocoa,xib,nsview,Cocoa,Xib,Nsview,我尝试将基于.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! } import AppKit func showXIBDefinedInPane
for sub in v.subviews {
Swift.print(v.subviews) // returns array [sub]
Swift.print(sub) // returns sub
Swift.print(sub.superview) // return nil!
}
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")
}
}
视图如何位于superview的子视图中,但superview属性设置不正确?在反编码/编码过程中是否会发生这种情况?要使其正确,我需要设置什么 下一个问题是,为什么在“查看调试”中正确显示
sub
,而在运行时需要它时却没有显示
编辑:(感谢Matt对此进行调查)
我的代码如下所示:
for sub in v.subviews {
Swift.print(v.subviews) // returns array [sub]
Swift.print(sub) // returns sub
Swift.print(sub.superview) // return nil!
}
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使用XIB定义
作为自定义类,嵌入的XIB使用WelcomeCMapView
作为自定义类
在顶部显示代码的问题是后处理的一部分,这是在加载嵌入XIB的NSViewController中的
viewDidLoad()
中执行的 “在反编码过程中会发生这种情况吗”这是个问题,好吧。笔尖加载相当复杂,连接起来需要一段时间。这在很大程度上取决于你什么时候说这句话。你能向后平移相机并显示更多的周围环境吗?还有,你怎么能不知道superview应该是什么,而实际上你刚刚说它是v
?显然这里的代码不是你真正的代码。请在上下文中显示您的真实代码。帮助我们重现问题。window
是否在showxibDefinedPanel
的末尾发布?XIBEmbedder.init中的xibName
怎么可能不是nil
(编码者:)
?XIB是否有一个顶级对象WelcomeCMapView.init?(编码者:)
调用super.init(名称:)
而不是super.init?(编码者:)
并且不从XIB读取属性(superview,frame,…)。xibName在以前的版本中是@IBInspectable的,但我现在使用派生类。是的,只有一个XIB顶级对象。然而,当在Xcode视图中调试嵌入器的所有子视图时,整个事情变得非常神秘(对我来说),但不是在窗口中。这似乎不是AlphaValue或isHidden的问题。