代码之家  ›  专栏  ›  技术社区  ›  Wizard of Kneup

视图层次结构不一致

  •  0
  • Wizard of Kneup  · 技术社区  · 8 年前

    我尝试将基于.xb的自定义视图添加到另一个基于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使用 XIB定义 作为自定义类,嵌入xib有一个 WelcomeCMapView 作为自定义类。

    上面显示代码的问题是后处理的一部分,它在内部执行。 viewDidLoad() 从 NSViewController 加载嵌入xib。

    0 回复  |  直到 8 年前
    推荐文章