Adding an NSView at top left and filling window - macos

I am programmatically adding an NSView to an NSWindow. I want to have the new view appear at the top left and fill the entire window.
I have been messing around with autolayout and manually setting frames and autoresizing masks (not at the same time, obviously), but I'm getting nowhere. Either the view doesn't resize at all, or it resizes proportionally (using autoresizing masks) but it won't fill the entire space. I must be missing something basic.
I am new to Mac Cocoa, although I'm quite experienced at iOS Cocoa Touch. On iOS, CGPoint 0,0 is top left. I assume on Mac from what I'm seeing that it's bottom left. How do you figure out what top left is?

Using the autoresizing mask like below should do the trick:
view.autoresizingMask = NSViewHeightSizable|NSViewWidthSizable
Absence of other resizing masks makes the margins inflexible. So whatever is the current margin (which is zero on all sides, when you add it to the window - Assuming the view occupies the full window frame when being added) is retained.
And top left would be the window's content view's height.
[[self.window.contentView frame].size.height]
I guess you already knew that. :)

Related

How to fix NSTextView's weird sizing inside a magnified NSScrollView

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.

NSScroller inside a NSScrollView does not change position when resizing the window (in Swift)

I have created a NSView with Interface Builder (Xcode 6.1). The NSView has constraints for each direction. When changing the window-size with the mouse manually, the NSView is getting a new size and the NSScroller gets a new position at the correct right border of the window, as expected.
When I set the window size manually (before it is made visible) with
myTextView.enclosingScrollView!.window!.setFrame(theRect)
or with
myTextView.window!.setFrame(theRect)
Then the window resizes well (as soon as it becomes visible), the NSTextView resizes also but the NSScroller (which is automatically part of the NSTextview and has not been created or modified seperately) does not move but stands in the middle of the ScrollView at its old position. The Text entered in the NSScrollView uses the full size and floats behind the NSScroller, which seams to stand in top of the text.
In the case, the Window is visible before setting the Window Size, then the scroll-view is truncated at the right side or bottom side.
When I change the window manually, after settzing the size and getting this behaviour, the NSScroller jumps to it's right position and the NSTextView is not longer truncated. So changing the Window Size manually does something more that I do programmatically.
What must I do, that the Scroller moves with the NSView, like changing the Size of the Window with the Mouse?
This is a typically problem when calling UI-functions from a background thread.
It can besolved, when calling from main-thread or forcing to called by the main-thread with this command:
dispatch_async(dispatch_get_main_queue())
{
// Place the UI Functions here
}
Please have a look at: Open File Dialog crashes in Swift

Superview not resizing with subviews

I have a window into which I horizontally add two subviews. Into each subview, I place a variable number of subviews made up of a vertical slider, a text field rotated 90 degrees and placed to the left of the slider and another textfield, placed just under the slider. The slider subview's constraints are done in code, the parent views are both done in IB. When I add more slider views to the left window than the subview can handle in its default size, it resizes horizontally and forces the window's content view (and window) to also resize horizontally. Great, that's just what I want. But if I add more slider subviews than can fit in the right subview, they just get squeezed together and the subview does not expand as the left. I layout the slider views using code with this category converted to support NSViews, instead of UIVews:
UIView+AutoLayout1: https://github.com/jrturton/UIView-Autolayout
The constraints for the left and right subviews are more or less the same. I can't figure out why the right view does not resize as the left view does.
Here is a link to a sample project that demonstrates the problem:
SliderTest
Some someone help me out with this?
Also, a secondary question as I think my slider view could use a little work:
When a view is rotated using setFrame(Center)Rotation, do the top, right, bottom and top edges remain along the same edges or do they reflect the new orientation of the rotated view?
Thanks
I found the problem. The constraint between the left view and right edge of the window was fixed at 233 instead of >= 233. I had this at some point in the past, as I was adjusting the constraints to achieve the desired behavior and just overlooked this one through the troubleshooting process.

Xcode IB: Inexplicable area?

I was wondering if anyone knew why IB has inexplicable high lighted areas on the odd nib here and there..
Below is an example:
What I mean is that light area within the area I marked out in red...
There's no views below the split view, there's no bounds which correspond to it and so far there's nothing complaining about "misplaced views" etc... What is it?
update: recently I worked out when it last happened that that weird "area" is always the same size as the rightmost NSView (whether its embedded in a NSSplitView or just 2 NSViews side by side.
Many thanks
Adrian S
It's due to a bug in XCode Interface Builder. And in my experiments it's been predictable according to the following explanation:
The lighter colored area is intended to highlight the container view of the current selection. So it you have an NSTextField within an NSBox, and you select the text field, the box will be highlighted. It's purpose is to dim out everything outside the scope that you can currently make constraints in.
You can see that it's a dimming down of everything outside the box, as if nothing is selected, the whole IB view port is displayed in the lighter shade.
The bug is that when you make a selection, IB clips the area of the container view to what's currently visible, and then adds this highlight as a rounded box 8 pixels larger. But when you scroll or resize the IB viewport, this clipped area isn't updated. So the rounded highlight box is seen to not cover the whole of the container view, just a clipped part (plus 8 pixels) of it.

Auto layout NSWindow respects minimum size in IB simulator, but not when running for real

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.

Resources