Make a view hidden by bindings

Hello,

Another problem for which I can’t find a solution (just fatal errors at launch).

I have a “inspector panel” with four superposed subview, each of them containing controls. At the top of the panel, I have a segmented control. I want the first subview to be visible (and only this one) when the first segment is clicked, the second subview when the second segment is clicked, and so on.

I have a programmatic working solution:

    on inspectorSelectorChange_(sender)
-- present the "page" associated with the selector item. First of all, hide all.

        selectorLayerDocument's setHidden_(true) -- "selectorLayerDocument" is bound to the subview, and so on:
        selectorLayerSelection's setHidden_(true)
        selectorLayerTenses's setHidden_(true)
        selectorLayerOptions's setHidden_(true)

       set layer to inspectorSelector's selectedSegment() as integer -- make the subview visible
        if layer is 0 then
            selectorLayerDocument's setHidden_(false)   -- show "Document" pane
        else if layer is 1 then
            selectorLayerSelection's setHidden_(false)   -- show "Selection" pane
        else if layer is 2 then
           selectorLayerTenses's setHidden_(false)   -- show "Tenses" pane
        else
           selectorLayerOptions's setHidden_(false)   -- show "Options" pane
        end if
    end

I wonder if there could be an “IB solution”, maybe a property linked to the control selected segment (I’m not sure it’s possible), and then bind the “hidden” flag of the subview in IB to this property. But how do I say “IF segment = 1” into the “Hidden” field in IB?

This is just to learn something, as my solution is already working fine.

Regards,

Welcome back, haven’t seen you around much lately!

I can’t think of a way to do this purely with bindings. In any case, this seems like a place to use a tab view, not a segmented control and 4 overlapping views – that way you don’t need any code or bindings.

Ric

Hello again Ric,

Yes, my job has kept me away from coding a looong time… programming must be a sort of spring disease for me :slight_smile:

Of course this is the equivalent of a tab view, but I know a lot of apps, including Apple’s Pages and Numbers and… Xcode itself, which don’t use tab views for inspector views.

There are three reasons for this:

  1. Tab views are ugly
  2. You can’t put an icon into a tab
  3. If there IS a tab view inside my subview, there will be a tab view inside a tab view, and I’ll end up with something as illegible as Microsoft Office’s preferences.

Another solution would be a toolbar, but you have even less control over the appearance of your buttons. And toolbars are more tool bars for me than tabs.

Ok, I’ll keep my code if there is no better solution. Thank you!

Totally agree!

Ric

Hi,

the mechanism of toolbar views and probably the tabs in Xcode or Safari is different.
Instead of just hiding/showing the views they are attached at or removed from a super view.
The advantage is that the views can be loaded dynamically to save memory and the transition can be animated.

This is a bit of (pseudo) code to avoid large if - else chains


property currentLayer : 0

set theViews to {selectorLayerDocument, selectorLayerSelection, selectorLayerTenses, selectorLayerOptions}

on inspectorSelectorChange_(sender)
	set layer to inspectorSelector's selectedSegment() as integer
	if layer is not currentLayer then
		removeLayerFromLayerView(item currentLayer of theViews)
		addLayerToLayerrView(item layer of theViews)
		set currentLayer to layer
	end if
end inspectorSelectorChange_

Hi Stefan,

Thank you for the code, I was just testing the interface, not optimizing code. What prevented me do add/remove subviews to/from a superview (a more elegant solution and easier to deal with in IB!) is that I’ve read somewhere that a view removed from a superview was released. I don’t want to send a message to a released object (even if there is surely a mechanism in ASOC to prevent this to happen).

Ok, I finally got the best from IB and have what I want without a single line of code!

  1. On my panel window, I create a segmented control with my nice icons.
  2. Then I add, just under it, a tabless tabview, disposing my controls on each pane.
  3. And now for the tricky part: I link the segmented control to the received action “takeSelectedTabViewFromSender” of the tab view.

The result is a tabview easily manageable in IB, with icons apparently belonging to the tab view, but a lot nicer. I really LIKE Xcode :slight_smile:

Anyway, maybe this solution is useful to other people around here. Thanks for helping me!