NSToolbarItem and Auto Layout - cocoa

I have a window with a programmatically created toolbar, which is populated with an NSToolbarItem that has a custom view defined in a xib file. If I check "Translate Masks into Contraints" for the view, then it doesn't resize itself correctly, so its content gets squashed even though I set its compression resistance priority to 750. If I uncheck that on the other hand, then I get a "Detected missing constraints" error at runtime. Also, the content of my view then resizes itself correctly, but it ends up clipped like so:
So it looks like the toolbar sticks my view into a container view and, in order to get the correct behaviour, I should set up layout constraints that allow my view to position itself correctly. However, I don't see how to access that container view... Any idea what I am doing wrong?
I am probably missing something obvious since one would think that this is a very standard setup, but Google didn't come up with anything.

Answering my own question, I opened a support request with Apple, the outcome of which is that this is now being treated as a bug by Apple.
In case anyone else runs into this, a good workaround is to create an intermediate view which contains the toolbar view as a subview with constraints #"H:|[toolbarView]" and #"V:|[toolbarView]", has translatesAutoresizingMaskIntoConstraints=YES and to use this view as the toolbar item. It then suffices to listen for size change notifications of toolbarView and to adjust the size of its superview accordingly.

Related

UIScrollView has ambiguous scrollable content but it has no content

Why does this scroll view have ambiguous scrollable content, when it doesn't have any content?
Presumably, you are laying this out with the intention of adding subviews (with proper constraints) to the scroll view at run-time.
But, Storyboard / Interface Builder has no idea what your code is going to do in the future.
You can either leave it as is and ignore the warning,
or
Tell Storyboard to stop warning you about it by selecting the scroll view and then selecting Ambiguity: Never Verify in the size inspector pane:
or
Add some content, such as a UIView that you will use to hold the UI elements you plan to add at run-time.

Silence "Views without any layout constraints may clip their content" on a specific view controller that has preferredContentSize set

I have a view controller that's fixed size (it can not be resized). This specific view controller is presented as a sheet in a window, I disabled the resizing by setting preferredContentSize. Since it can't be resized anymore, I left the view without any constraint. However, when I build the app, I got a lot of warnings that says :
Views without any layout constraints may clip their content or overlap other views.
I do know that if you don't add any constraints in a standard window it will clip when it is resized. However, resizing is disabled on my specific window so that I know it won't happen. Is there a way to silence this warning? There are a lot of views on this specific view controller and it's blocking other useful warnings that I may encounter in the issues navigator.
This view controller is presented through a "Sheet" segue.
I had a single warning saying the same thing.
Editor > Resolve Auto Layout Issues > Add Missing Constraints
worked for me.
If it doesn't for you, something else under "Resolve Auto Layout Issues" might work.
For me what worked was the reposition the elements: Drag them again into position and drag their height and width to the desired size again. Then click on "Resolve Auto Layout Issues" and click on "Reset to Suggested Constraints".
Since no one answered this, here is how I fixed it. For each view on the form change the Layout option from Automatic to "Translates Mask Into Contraints". If you want it anchored to the upper left corner, select the top an left red handles and leave the lower and right unchecked.
For me what worked was; select the last element that cause the warning
size inspector tab > layout > Autoresizing Mask

Xcode 8 attribute "hidden" does not hide view in Interface Builder

seems like Apple change how Interface Builder behaves in Xcode 8? Because when I check hidden in Attributes Inspector on a view in Interface Builder, that view is still visible.
This makes it very tedious to work with views where some views needs to be the view with the highest "z value", the front most view that is.
Is there some other way to show the green view in this example, than to change the order of them to the right (i.e. change their "z value")
In the image below hidden is checked, but I still don't see the green view below. You can download this trivial project at github
When the project is run, the green view is indeed shown, but the issues is that it is annoying when working in Interface Builder.
Am I missing something?
I have the same opinion on it and I also believe that it's annoying. I with they gave you the choice to update the actual storyboard before runtime or not but they didn't so for now we have to deal with it.
There is a quick alternative option though. Hidden will not update in the storyboard but alpha will. If you change the alpha it will update in the storyboard so if you want to see the view behind it just change alpha to 0. You can always change it back easily or if your doing it in code, instead of unhiding your view just change the code so the alpha is set to 1.
How about unchecking the installed checkbox of the red view?
This has also the flaw that you have to remember to reinstall it, but you don't have to change the z-order of your views.
This is deliberate. We wouldn't want a view to be hidden from you, the editor, just because it will be hidden when the app runs. You can easily select a covered view, such as the green view, using Shift-Control-Click on the red view (or use the document outline at the left of your screen shot).

OS X App - Cannot Resize App Window

I have an OS X app originally built using Xcode 4, now using Xcode 7. When "springs-and-struts" was superseded by constraints, I reworked the UI to use constraints. Simple enough, and seemed to work well.
Fast forward two years after first release, and for the second release I needed to add controls and increase the height of the main app view. Unfortunately, my test team is using smaller screens and cannot see the whole view. They need to resize vertically.
Problem - even though the resize controls box is checked, the window cannot be resized. The controls do not show at run time. I tried
Setting lower minimum window content size height, but that did not change anything.
Changing content compression resistance did not change anything.
I am thinking this issue has something to do with constraints.... Any ideas on how to get resize to work?
Edit: After playing with a new test app some, I am more certain the problem is due to constraints. I have a control where I have constrained leading and trailing space to superview and width - there went horizontal resize.
I really need to have a view where the user can resize the window, but scroll the content. However, in this case, the content is other controls. I think on iOS, I would use a UIScrollView. On OS X, I have tried a scroll view control and have tried embedding in a scroll view, and neither have the desired effect.
I had the same issue and solved it by adding a view to be used as a "container" in the view controller.
Pin the top left corner of the "container view" to the view controller (leading space 0 and top space 0). Add equal width and height constraints on the "container view" to the view controller. Then move all your objects into the "container view" and add your object constraints on the "container view" not the view controller.
In my case, it happened in this way (Xcode 13.1).
I mistakenly added a view from IB outside of the window view hierarchy. The new view was added as a separated object (a top node in the interface builder file). I added the new view into the window by drag-n-drop.
I found the new view had different behaviours, for example, I couldn't set the top space constraint. With this view in the view hierarchy, I couldn't change the window size (content view size) at all.
I removed the view and added another in the view hierarchy, it worked as normal.
I think IB initialises the view differently if it is a separated object (top node of the interface builder file).

How do you use NSScrollView with auto layout?

Ok. I've been at this over and over. I've seen blogs and cocoa dev threads.
I've seen Kyle Sluder's proposed solution, but have yet to find a solution that really works.
How can you position subviews of an NSScrollView with auto layout?
Is it just silently broken ?
Nothing seems to work.
Ok, old question, but this particular issue is a personal bugbear of mine so I'll answer it anyway!
The first thing to note is that an NSScrollView contains an NSClipView, which itself has a view outlet called documentView. These are all added for you when you drag a new scroll view into your storyboard or nib file. By default, the document view is an NSView called simply "View". If you're using a custom view, you can just select this and set its type in the inspector on the right to whatever you want. Otherwise, you'll be adding subviews to it.
The big thing that is easy to miss here is that, by default, the document view has its layout set to 'Translates Mask Into Constraints'. This is fine if the content size will never, ever change, and if that's the case you can simply set the frame of the document view to whatever you want and leave it at that. If you want it to automatically resize itself to fit its content however, there's a few things you'll need to do.
First off, that document view needs to have a completely unambiguous size. If you're using a custom view, I'd recommend giving it an intrinsicContentSize. You should also set 'Intrinsic Size' in IB's inspector to 'Placeholder' and give it a suitable value, or you'll get a bunch of autolayout warnings. If your document view gets its size from its content, all of the subviews must be linked in an unbroken chain from top to bottom, and from left to right, such that the content knows exactly how big it ought to be. This is quite an art in itself, so I won't go into it. A simple example where you have only one subview would be to pin its top, bottom, leading and trailing constraints to its parent, but as noted above if you're doing this, you might as well just set the type of the document view.
Now the fun bit. Select your document view and set its layout to 'Automatic'. Next, add top, bottom, leading and trailing constraints to its superview with a suitable value. I'm using zero, but you might want a small border. Finally, select the TRAILING and BOTTOM constraints you just made and set them to '>=' (greater than or equal) and a priority of 500 or less. The priority is very important, as it has to be less than the priority that the clip view uses to determine its own minimum size. Too high and the clip view will be forced to remain larger than its content, making it impossible in turn for the scroll view to be smaller than its content, rendering it useless.
The technical details aren't important. Just remember to set the document view to layout: automatic, pin all edges, and make the trailing and bottom constraints >= and priority 500.
Note that this will cause your content to hug the top-left corner.
Have you tried setting the document view's setTranslatesAutoresizingMaskIntoConstraints to TRUE?
[_scrollView.documentView setTranslatesAutoresizingMaskIntoConstraints:YES];

Resources