I have a radio button and a label. I need to have them aligned horizontally in an NSView, such that the radio button is to the left of the label:
[Radio Button] [Label]
This seems a pretty trivial thing to do, but when do it in IB, I end up with the Label on top of (or maybe under) the button. If I instead programmatically apply constraints, I get precisely what I want. Here are the programatic constraints:
[self addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"|-5-[_deviceButton][_statusLabel]-20-|"
options:NSLayoutFormatAlignAllBottom
metrics:nil views:views]];
In IB, I use "Trailing Space to Container", "Top Space to container" "Bottom Space to container", "Leading space to Container" for both views and I set a "Horizontal Spacing" constraint between the two views. What could I be missing in IB? I've done this before, but can't for the life of me get it right?
Thanks
If I'm understanding you correctly, you want the group of both buttons to be centered inside your view.
In that case, embed the two items in a view (select them, then go to Editor > Embed In > Custom View), then you can center that container view horizontally in your view.
You don't want all four of those constraints for both elements. Your button, which you want to be the leftmost of the two views, should be constrained to its container on the top, leading, and bottom; the label should be constrained to its container on the top, trailing, and bottom. The constrain the button's right edge horizontally to the label's left. (You'll notice that that's exactly what your visual format winds up generating.)
Related
I got an NSTabView inside an NSView. That NSView is in an NSClipView, which in turn is in an NSScrollView. It looks like this (NSTabView in green, and NSView in red):
As you can see, the content of NSTabView gets clipped, and no scrollbars appear (since the view doesn't expand beyond the window).
How can I make NSTabView take up as much space as it needs (doesn't clip out), and expand the NSView with it? Then, NSScrollView can deal with the scrolling of the overgrown NSView.
Since my content changes dynamically, I don't want to put in some hard values for the width and height of NSTabView's superview.
This is only part of it; here's now the overall hierarchy looks:
I want the NSTabView's superview to be scrollable instead of clipping out, like this:
The setup I'll describe is for an NSTabView that will pin to the top, left, and right sides of the scroll view. Note the NSTabView could be replaced with any other NSView, the setup is the same.
Starting with you putting a scroll view into the xib/storyboard, you'll have NSScrollView -> NSClipView -> NSView (document view). Constrain the NSScrollView to the edges of the window. Drop your NSTabView onto the NSView instance. Add constraints so that your NSTabView edge constraints equal the NSView and define a height constraint either explicitly or implicitly with other content inside the tab view that defines it.
Personally I like to change the NSView instance (document view) layout to use constraints, by default it uses autoresizing masks and this makes it difficult to keep it in sync with the NSTabView. We want the document view to be pinned to the top, left, and right sides of the scroll view. The size of this view is what determines the scrollable region so we want it to be the same size as the NSTabView so the height of the tab view will determine the scrollable area.
To change this, select the document view, and under the Size Inspector we want to change the "Layout" type to "Automatic".
Lastly, add constraints to the top, left, and right and you should be good to go.
If you want the scroll view to start at the top rather than the bottom, you should subclass the document view and override isFlipped:
class FlippedView: NSView {
override var isFlipped: Bool { true }
}
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.
I'm trying to understand how to use Auto Layout but I haven't been able to wrap my head around how to accomplish something like this using it. I have an iPad ViewController with two subview views. I'd like the layout to work like in this representation but I'm not clear on which values to set. particularly the relationship between the two subviews:
The left view should be pinned to the superview's top, left and bottom edges (with your padding) It's right edge should be pinned to the right view's left edge.
The right view should be pinned to the superview's top, right and bottom edges (with your padding). It should have a width constraint with a constant value, which you would set to the appropriate number on rotation.
In IB, you'd create an outlet to the width constraint. In code, just assign it to a property as you create it.
I'm using Autolayout to set up quite a lot of labels and buttons in a view. One button needs to be exactly betwwen 2 UILabels and I don't know how to accomplish that. I try to get the position on one label, the position of the other, do the math, etc. But since it's using autolayout, it turns out that the frame.origin.x property is always 0.
So any clues on how to do that?
thanks in advance,
One possible way to do this using the designer is to place a container that will fill the space between the two labels. Just drag a View onto the design surface and make sure that you have the following constraints: Top Space to the top label with default value and Bottom Space to the bottom label with default value.
Once you have this container simply place the button as a child of this container and centre the button horizontally and vertically in the container. That should do it.
This could also be done with code. Let me know if sample code is needed.
I have an NSOutlineView which I draw badge numbers to the right side of cells using drawAtPoint:, NSAttributedString, and of course NSBezierPath. My problem exists when resizing of the outline view occurs when within a subview of an NSSplitView. The badges move along with the resize to the left or right. When they get to the text of the cells themselves they do not stop or truncate the text under them. It just flies right over.
Is there a way to have the cell recognize the custom drawn view next to it and truncate text accordingly? I have tried the solution PXSourceList already, but that did not help either.
"PXSourceList solution" working good. You subclass NSOutlineView and overload frameOfCellAtColumn for this particular task. At this function you need to decrease width of cellFrame, returned from super call, by the width of your badge plus padding.