1

I am making a UI completely programmatically. (no IB) I made a NSWindow, and attached a NSSplitView. The problem is first subview of the split-view always become collapsed when window shows up at program startup.

How can I force to show all the subviews of the split-view at start-up?

eonil
  • 83,476
  • 81
  • 317
  • 516

1 Answers1

1

This kind of problem is hard to prove the reason because it needs knowledge of internals of closed source program.

So reason unknown, but subviews are shown when I set NSSplitView's initial size to non-zero value before adding subviews.

NSSplitView* v  = [[NSSplitView alloc] init];
NSView*      v2 = [[NSView alloc] init];
v.frame  = NSRectFromCGRect(CGRectMake(0,0,100,100));  // Added this line.
v2.frame = NSRectFromCGRect(CGRectMake(0,0,50,100));  // Added this line.
[v addSubview:v2];  // And then, add subview. 

I guess NSSplitView has some internal subview layout behavior by it's current available size. As far as I observed,

  • Adding subviews to zero sized NSSplitView never work correctly.

Update

Starting with OS X 10.10, Cocoa introduced a new class NSSplitViewController, and it works quiet nicely. I strongly recommend to use this. It's fully auto-layout based, so you need to use auto-layout constraints to set sizes.

I wrote a working example project, and here's copied code snippets.

    func make1() -> NSViewController {
        let vc1     =   NSViewController()
        vc1.view    =   NSView()
        vc1.view.wantsLayer =   true
        vc1.view.layer!.backgroundColor =   NSColor.blueColor().CGColor
        return  vc1
    }
    func setup1(vc1:NSViewController) {
        /// Layout constraints must be installed after the view is added to a view hierarchy.
        split1.view.addConstraint(NSLayoutConstraint(item: vc1.view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: 20))
        split1.view.addConstraint(NSLayoutConstraint(item: vc1.view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.LessThanOrEqual, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: 300))
    }

    split1.addSplitViewItem(NSSplitViewItem(viewController: make1()))
    split1.addSplitViewItem(NSSplitViewItem(viewController: make1()))
    split1.addSplitViewItem(NSSplitViewItem(viewController: make1()))

    setup1(split1.splitViewItems[0].viewController)
    setup1(split1.splitViewItems[1].viewController)
    setup1(split1.splitViewItems[2].viewController)
eonil
  • 83,476
  • 81
  • 317
  • 516
  • 2
    ... is this supposed to be an answer? It looks like a comment, but I would trust that with 12k reputation you would know the difference between a comment and an answer. – BoltClock May 22 '13 at 16:46
  • @BoltClock Thanks for care. I updated my answer to make it sense. (so doesn't look like a non-solution stuff anymore) If this still somewhat inappropriate, please let me know why. Because it means I don't know the why, and I always want to follow community etiquette. – eonil May 23 '13 at 01:02
  • 1
    @ClintonWard Well, I need two more days to accept my own answer. And also, I still wish someone will bring better answer than mine. – eonil May 23 '13 at 01:05