Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
632 views
in Technique[技术] by (71.8m points)

macos - NSTableView with +/- buttons like in System Preferences using only Interface Builder

Apple commonly places +/- buttons below tables (NSTableView), e.g. in the System Preferences for Network or User & Groups. See image below:

Table Bottom - User & Groups System Prefs

How can I place identical buttons below my tables directly in Interface Builder without manipulating any interface elements in my code or subclassing any element classes?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If the table has a fixed width, the easiest way is to just use a segmented control NSSegmentedControl. First add it to your view or window:

Segmented Control

Change its Style to Small Square, the Mode to Select None and increase the number of Segments to 4 (or keep it at 3 if you only need + and -):

Segmented Control Setup

The +, - and other buttons are predefined images of the AppKit framework (NSAddTemplate and NSRemoveTemplate) and directly available in Interface Builder. E.g. you could setup the first three segments as follows:

Segment 0 Setup Segment 1 Setup Segment 2 Setup

For demonstration purposes I made the - segment disabled. Unlike most other buttons, disabling a segment of a segmented control only dims the image/text, it does not change the button background. Only disabling the whole segmented control changes the background (and of course disables all segments).

Of course, the last segment should always be disabled, otherwise it would be clickable and change its background when being clicked. As it contains no image or text, it still looks the same after it has been disabled.

Switch to the size setup and uncheck the Fixed checkbox for all segments, except for the last one, make sure it is checked for the last one:

Segment 0 Size Setup Segment 1 Size Setup Segment 2 Size Setup Segment 3 Size Setup

Unchecking Fixed makes the segment width dynamic, that means it will always match the minimum width required for the content.

Finally place the control directly below the table and resize it to match the table width. Here's the result:

The Result

Almost perfect, don't you think?

Things get more difficulty if the table width is dynamic (e.g. the table resizes together with the window resizing). A segmented control doesn't support autoresizing, that means you would have to programmatically change the width of its last segment each time the table is resized. Of course, that is not too hard to do and requires only little code but there is one alternative solution that requires no single line of code.

Decrease the number of segments by one and replace the last segment with a gradient button (NSButton) without title:

Gradient Button

Its background looks exactly the same as a segmented control, yet it does support autoresizing to always match the size of the table. There is just one problem: It is clickable and this time disabling it doesn't work as this would change the background. Instead just change its Type to Momentary Change (which means the app wants to control the UI change itself when the button is clicked):

Gradient Button Setup

And after the button has been placed correctly and made resizable, the result looks as good as before but this time the table can be resizable and the buttons on the bottom will always fit perfectly.

Sample Window Small Sample Window Bigger


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...