视图层次结构不一致

时间:2018-08-07 17:18:41

标签: 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!
}

如何在超级视图的子视图中显示视图,但是未正确设置超级视图属性?解码/编码期间会发生这种情况吗?我需要设置什么才能使其正确?

下一个问题是,为什么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")
    }
}

键是XIBDefinedXIBEmbedder这两个类。前一个可以从XIB加载,后者可以在XIB中使用。因此,以后的嵌入式XIB使用XIBDefined作为自定义类,嵌入的XIB具有WelcomeCMapView作为自定义类。

顶部显示问题的代码是后处理的一部分,该后处理在viewDidLoad()内的NSViewController内加载嵌入的XIB。

0 个答案:

没有答案