How to perfectly mimic toolbar buttons as in Finder, Safari, or other default apps? - macos

I'm trying to create an application that would be as standard as possible in terms of style.
An image is worth a thousand words: I can't figure out how to make my buttons the same size as in Apple's programs such as Safari or Finder.
As you can see, the sizing I've set in interface builder don't seem to match the size the buttons get when I run the app, but maybe that part doesn't speak in pixels but in points or something? Also, textured rounded button has only width editable, but not height.
In this case, these are NSButtons, but I guess I'll have a similar problem with other control types...

I found it out! The problem was with neither of these two parts outlined in the screenshot, but in the "Toolbar" item, higher in the hierarchy.
There is a Size attribute in the Attributes inspector which defaults to Small, but you can set it to Regular instead, and then the buttons get the same sizing as in Finder and all.

Related

How can I make window zooming respect auto layout constraints?

To keep things simple, let's say I have a window containing a single view, which has auto layout constraints binding all 4 sides to the window container view with offset 0. And assume that this view also has a constraint setting its aspect ratio to a constant value. If I resize the window manually, then then window nicely maintains the desired aspect ratio. But if I click the little green zoom widget, then the window fills up the whole screen, regardless of the aspect ratio, with part of the view being above the top of the screen. Is there some way I can make zooming resize the window as big as it can be, without violating auto layout constraints?
I couldn't very well detect this problem in the delegate method windowWillResize:toSize:, because that doesn't tell me which screen it's thinking about putting the window on. I could try to fix the window size in the windowDidResize: delegate method, at which time I do know what screen it's on, but I'm not sure exactly how to do that without reinventing Auto Layout's wheel.
Apparently someone thinks I wasn't explicit enough, so I'll try again. Steps to reproduce:
In Xcode, create a new macOS App project using XIB interface.
Open MainMenu.xib and select the window.
Reshape the window to be approximately square.
Using the Attribute Inspector, set the Full Screen behavior for the window to Auxiliary Window.
Drag an Image View from the library and drop it in the window.
In the Attributes Inspector, set the image view to show the NSComputer image and scale axes independently.
Expand the image view to fill up the window content area.
With the image view selected, click the button to add new layout constraints.
Add 5 constraints, binding the 4 sides to the container, and setting the aspect ratio. (see screen shot)
Build and Run.
Observe that if you resize the window by dragging an edge or corner, the aspect ratio remains fixed.
Click the green zoom widget in the title bar of the window, and observe that the window expands without regard for the aspect ratio constraint, cutting off part of the image.
I just set up a test project exactly as you specified, and when I invoke the window zoom widget, the window expands and retains its aspect ratio i.e. it works as expected. The only thing I can think of that might be causing your issue: maybe your content hugging and content compression resistance priorities are at odds with your constraints? Mind you, I just left them at the default values and it worked fine. Unfortunately Mac/AppKit development (esp. when using IB) is rife with these kind of odd bugs and weird behaviour, probably because Apple has not given it any love in years, so bugs creep in/fester and they are clearly so DONE with developing UI the 'old fashioned way'. (Using SwiftUI to make a Mac app is just as frustrating, in different ways, so I'll stick with what I know). FYI, I used Xcode 13.4.1 to create this test project. Good luck!

How to properly use sizing with Cocoa

ALL,
NSSmallControlSize page has following explanation:
This constant is for controls that cannot be resized in one direction,
such as push buttons, radio buttons, checkboxes, sliders, scroll bars,
pop-up buttons, tabs, and progress indicators. You should use a small
system font with a small control.
Is there any way to set the size for other controls? Namely NSComboBox.
Unfortunately the documentation is not talking about that. It's not even mentioning if it is at all possible.
TIA!
As the page describes, the constant is for controls that cannot be resized in one direction. Combo boxes, like the listed controls, cannot be resized vertically. Therefore it makes sense that the constant would apply to combo boxes.
This can be quickly verified by creating a combo box in Interface Builder, clicking on the Size inspector, and setting its size to Small. Since this works, we can conclude that the small size is compatible with combo boxes.

How to create consistent toolbar buttons with icons

Desired look
I wish to make a toolbar for my app that will contain some simple buttons, each with a single monochromatic icon. Here is an example of some toolbar buttons similar to I'm trying to achieve, from Mail's compose window:
Notice these buttons have a consistent size, inner padding, padding, and shading. This is a pretty consistent style across macOS, present in Mail, Safari, Finder, etc. This leads me to suspect there's a standardized UI component for creating such buttons.
If I use a segmented control, each button looks correct, with each icon being correctly padded:
Now I would like to add individual buttons that match the style.
Attempt 1
My first attempt was to add a "Push Button" (NSButton) to the toolbar:
This resulted in a wide button that's a bit too short, and not lined up with the segmented control:
Attempt 2
My second attempt was to use a segmented control, with only 1 segment.
This resulted in a button that's the right shape, size, etc., but it was off center relative to its label.
Naturally, I can manually adjust the button to match the goal, but I feel like I'm missing something. What's the proper way to create these standard buttons?
This is actually quite easy to do and you were close already.
You can use NSButton for that. Note that it has different styles (defined in NSButton.BezelStyle) to choose from. The default one is the one to use inside windows and modals. But for toolbars, to match the style of segmented controls and search bars, you can choose the style .texturedRounded.
You can also set the style via Interface Builder. Note that you have to select the button itself, not the toolbar item around it.
To get the correct size, you seem to set the icon within the toolbar item, not the button itself.
Here is my result:

Seeking a simple Mac OS NSTextView example using AutoLayout

After much reading and experimenting, I still cannot get a simple TextView to resize fully in the horizontal direction using Xcode 5.0.2 in Mavericks. It resizes partially as the window is resized, then stops with long lines wrapped around even though my containing NSScrollView continues to resize as expected (it has four default constraints and no horizontal scroller).
Can anyone point me to a simple code/IB+AutoLayout example, preferably just a window containing just an NSTextView dragged in from the IB template library --- one that works? The Apple TextEdit sample code is almost irrelevant for this purpose although it does resize horizontally quite well. Also, there is the clip view for which I can find little information.
Any other tips appreciated.
Thanks.
Answering my own question:
Turns out that my problem had nothing to do with AutoLayout and little to do with NSTextView. It was the textfile I was using to test my code! This file was composed of records with tab-delimited fields.
Turns out that NSTextView comes with a default NSParagraphStyle with predefined tab stops that end at character 56 whereas my test file had tabs beyond that. Therefore, my lines wrapped around at the last defined tab no matter how much I stretched the window.
After changing my search terms, I found what I needed at the following links:
Premature line wrapping in NSTextView when tabs are used
How to have unlimited tab stops in a NSTextView with disabled text wrap
Apologies for wasting bandwidth.
Not sure why such a simple thing does not work in your case, but nevertheless here's what I did in Xcode to get an NSTextView follow window resize:
Create a new project (not document based in my case but it doesn't really make a difference)
Drag a NSTextView from the palette to your window. Align all four edges with the window edges.
Open the "Add constraints" pop-up (second button from the segmented control on the bottom-right part of your IB view.
Each of the four spacing constraints should show a number equal to the distance of your text view from the container window. If you aligned them, this number should be either 0 or -1. Click the down arrow for each of them and select "Use Current Canvas Value". Do it for all four. Make sure no other constraints are selected.
Click on "Add constraints" on the bottom of the panel.
Run your project. Your textview should resize with the window.
Also, as Jay's comment mentions, make sure you do not have any "leftover" constraints in your view. You can check this either by observing Xcode's warnings, or manually by inspecting your view's constraints by going to the Size Inspector tab (4th tab on the Utilities bar).
If you need to have your textview arranged in a more complex layout, it might be worth taking a look at the AutoLayout Guide.

How do I get Mac Toolbar Items that look like the standard toolbar buttons?

I'm working on some updates to my first Mac app and I'm trying to get my window's toolbar buttons to look like the toolbar buttons on EVERY standard Mac app. However, for the life of me, I can't find a button type or a barbutton type that gets me what I'm looking for. Am I missing something?
Here is an image showing several Mac apps (Preview, Finder, and Safari) with toolbars at the top which have very-slighty rounded corner buttons which also have a slight gradient on them, etc.
However, in my .xib I've got a toolbar and I've dropped every kind of button I can find on the thing and nothing looks like the standard Mac button.
The first button looks pretty close, but it's clearly not the same color. Am I missing something?
#Matt Ball is right - you can use NSSegmentedControls, even for single one-time click buttons. Just set the number of segments to 1, and set the mode to "Select None".
One of my shipping apps uses this technique, see below:
All of the controls there are NSSegmentedControl, including the single one.
Update: there are a few standard button icons which are meant for toolbars. The NSImage Class Reference has a list.
In the above screenshot, only two of the buttons are using built-in images: NSLeftFacingTriangleTemplate, and NSRightFacingTriangleTemplate. The others I drew myself.

Resources