I'm trying to get the hang of NSViewConstraints. I like them a lot; they make a lot more sense to me than the previous system.
I have a window, a 22 pixel-tall subview spanning the top of it, and a tabless, borderless NSTabView beneath it. The goal is to have the top subview never resize its height.
Without any constraints, auto formatting takes care of most of the work. The only trouble is resizing the window causes the upper subview to change its height. My seemingly logical response was to pin the height at 22. I left margin constraints alone, since the NSTabView was already handling resizing well.
By pinning the height of the upper subview, the window now refuses to resize vertically! I don't see any documentation anywhere saying this is expected or the logic behind it. I've messed with various constraint configurations to overcome it but nothing works.
Two questions:
Why is pinning the height of one subview freezing window height resizing? What is Xcode's logic?
What constraint setup will achieve the desired positioning?
I just tested creating a window as you describe, and pinning the height of the 22px view. This created one user constraint on the view for it's height.
However, it also created 2 constraints on the parent view (the window's content view), one for the Top Space to the 22px view, and a second for the Bottom Space to the 22px view. These constraints are what's preventing you from resizing your window. You should select the second constraint and delete it (but leave the first one in place as it's fine).
Related
I have an NSTextView inside NSScrollView/NSClipView, the usual setup. When I magnify the scroll view with [NSScrollView setMagnification:...] and resize the window, the width of text view's frame gets constantly larger, regardless of whether I stretch or shrink the window.
If the scroll view is not magnified, text view behaves normally. I have tried removing constraints and disabled subview autoresizing, but nothing helps. Whenever i set any sort of magnification, text view size changes on every call to resize. If the magnification is under 1, it shrinks.
Any bugs in TextContainer shouldn't make it wider either, as I've set textContainer.widthTracksTextView = false;
I am trying to keep the textContainer centered in my NSTextView by setting insets to it, but it gets impossible with the varying sizes. I've gone through my code and nothing should make it resize. Is this a bug or does the setMagnify: cause problems with constraints or some other math in LayoutManager?
For anyone trying to figure this out:
This is caused by a minimum width constraint for the magnified view, or any of its subviews. Seems like a bug, as I can't wrap my head around how this would be intended behaviour.
Just remove the >= constraint and do something to limit the size in run-time if needed.
I'am using autolayout with NSSpliView, the setup is as following on the picture
The split view is in a window which can resize, when it resizes, the divider is changing proportional 50:50, how to change this, so that the height of the bottom view stays and the top view gets resized (but no more than 124px) but still have the freedom also to change it manually by dragging the split?
So just to recap you have three requirements,
Bottom view stays the same size on resize
Reduce the holding priority if the top view (select the NSSplitView to get the correct inspector)
Top view cannot resize more than 124px
Add a inequality constraint which sets the height of the view to less than or equal to 124px. You can do this in IB. It will also be a good idea to create a IBOutlet for this constraint in your custom view of controller class for the next step...
When the divider is moved the top view should be able to get smaller than 124px.
I not entirely sure but checkout the NSSplitView delegate method such as splitView:resizeSubviewsWithOldSize: or splitViewDidResizeSubviews:. When you resize with the divider the delegate method should override the height constraint to be the current resized size. So something like the following in the delegate method
self.heightConstant.constant = NSHeight(topView)
Or you could just remove the constraint and re-add it later when needed.
I have a window I'm setting up with auto layout. There is a view in the middle of the window that contains three controls, and I would like the window to refuse to resize horizontally smaller than the intrinsic size of those three controls.
The outer buttons both have horizontal space constraints to "stick" them to the outside of their superview, and the checkbox in the middle has a horizontal space constraint sticking it to the left side of the "Sync text" button. There is also a >= constraint between the "Sync outline" button and the checkbox, to make sure they don't overlap, but the checkbox prefers to hang to the right. All these constraints have a priority of 1000. The window itself has no minimum size specified.
When I use the "Simulate Document" command in Xcode, everything works as I'd expect, and the window won't let you size it smaller than in the screenshot above. However, when I run my application, the window does allow resizing smaller than that width, so that the buttons start to shrink and eventually the controls overlap each other. I'm not implementing any of the size related window delegate methods, so I don't see any place in the app's code where it might be influencing the resizing.
Any ideas on what could be causing this difference in behavior?
OK, I finally figured out what the heck was going on here. It turns out the problem was that I was implementing the -splitView:constraintMinCoordinate:ofSubviewAt: delegate method (as well as the maxCoordinate one) to restrict the size of the split subviews in the vertical direction. Yes, restricting the vertical resizing of the split view affected the horizontal layout of the buttons.
It appears that what happens is that, if you implement those delegate methods, NSSplitView reverts back to using autoresizing masks to layout the subviews rather than auto layout constraints. Since the view containing those buttons is no longer participating in auto layout, the buttons smush together when you resize the window small. In the simulator, the split view doesn't have a delegate set, so all the auto layout stuff works fine in that environment. Note that merely having the methods implemented is enough to trigger this, even if they just return the proposed coordinates unchanged.
The solution ended up being quite easy, which was to delete the delegate methods and replace it with a vertical constraint on the subview to restrict its size instead.
I'm having trouble getting a UIScrollView to respect the constraints I put in interface builder.
All I need to be able to do is set the content size of the scroll view from within IB.
The UIScrollView contains a single UIView.
Constraints on the UIScrollView:
Constraints on the UIView:
I've read through the documentation, and so have set things up as follows:
the UIScrollView has constraints pinning it to its superview, thus defining its size from outside
the UIView (content) has a fixed size (through width and height constraints)
the UIView is pinned to the UIScrollView, thus defining the content size
However, IB won't let me enter these constraints. If I change the 'Bottom Space' constraint between the view and the scroll view, shown in the image as -2196, to 0 (thus pinning the lower edge of the scroll view), then the 'Top Space' constraint resets to a non-zero value. The same happens in reverse. (I haven't yet tried in Xcode 5, which has a far saner approach to invalid constraints in that it doesn't just throw yours away when it feels like it.)
What am I missing?
Every time I've tried to do something even mildly sophisticated with constraints in Xcode 4's Interface Builder, I've eventually given up and either written the constraints in code or switched back to springs'n'struts and layoutSubviews (usually after crashing Xcode a few times).
That said, there is another approach to laying out a scroll view with content in IB. Just make the scroll view as big as its content size, and rely on the view controller (or some containing view controller) to resize the scroll view (or its superview) and let the constraints shrink down the scroll view's frame at runtime. The window's root view controller will always set its view's frame to the screen size, regardless of its size in the nib or storyboard, and that resizing flows down the view hierarchy.
I described this approach in more detail in this answer.
If your scroll view's content size is really supposed to be 2196 points tall, this probably won't work so well. I don't have anything better to suggest in that case.
I'm new to the Dynamic Layout concept introduced in Cocoa applications with Lion 10.7.
I've been playing with some examples and almost all works as I expect. But, there is one thing I've been unable to get: Flexible Height in some elements.
I have one NSTextField element where I can set properly the following constraints:
Leading to trailing -> To keep it "near" to left and right border resizing its width.
Vertical space -> To keep it "near" to the previous vertical element.
I also set:
Vertical space -> To keep it "near" to the bottom border.
Height >= x -> With the previous one, to make its height "flexible" and adjustable to the view's height when resized.
When I test it, it works in the "horizontal axis" (location and size) but it doesn't allow me to resize the window's height (it's fixed).
If I delete the "Vertical space" constraint that attaches the NSInputText to the view's bottom, I can resize the window but the NSInpuntText's height remains unchanged.
Another annoying thing is that the "default" height constraint for the NSInputText (that on "pink" color) can't be deleted or modified. Whenever I do that a new one is created.
Any ideas?
Thanks.
UPDATE
If I use a "Text View" (NSScrollView with a NSTextField inside) instead of a "plain" NSTextField I'm able to create the behavior I want with any problem.