Can anyone explain what is the difference between Frame Rectangle and Alignment Rectangle in the size inspector?
Frames describe where to place views on the screen and how big those views will be. When laying out views, constraints use a related geometric element called an alignment rectangle.
The alignment rectangle is based on the presentation of the item’s content, Auto Layout uses the alignment rectangle instead of the item’s frame rectangle.
By working with alignment rectangles instead of frames, Auto Layout ensures that key information like a view’s edges and center are properly considered during layout.
Unlike frames, a view’s alignment rectangle should be limited to a core visual element. Its size should remain unaffected as new items are drawn onto the view.
Consider the left side of Figure -1. It shows a view drawn with a shadow and a badge. When laying out this view, you want Auto Layout to focus on aligning just the core element—the blue rectangle—and not the ornamentation.
Figure - 1 : A view’s alignment rectangle (center) refers strictly to the core visual element to be aligned, without embellishments.
The center image in Figure -1 highlights the view’s alignment rectangle. This rectangle excludes all ornamentation, such as the drop shadow and badge. It’s the part of the view you want Auto Layout to consider when it does its work.
The right-hand rectangle in Figure -1 encompasses all the view’s visual elements. It encompasses the shadow and badge. These ornaments could potentially throw off a view’s alignment features (like center, bottom, and right) if they were considered during layout.
Figure -2 Auto Layout only considers this view’s alignment rectangle when laying it out as centered in its superview. The shadow and badge don’t affect its placement.
Reference: link
From Apple's old Auto Layout Guide:
Layout Operates on Alignment Rectangles, Not on Frames
When considering layout, keep in mind that the frame of a control is
less important than its visual extent. As a result, ornaments such as
shadows and engraving lines should typically be ignored for the
purposes of layout. Interface Builder ignores them when positioning
views on the canvas—in the following example, the Aqua guide (the
dashed blue line) aligns with the visual extent of the button, not
with the button’s frame (the solid blue rectangle).
To allow layout based on the presentation of the content rather than
the frame, views provide an alignment rectangle, which is what the
layout actually operates on. To determine whether your override is
correct on OS X, you can set the NSViewShowAlignmentRects default to
YES to draw the alignment rects.
So, that pop-up menu in Xcode is providing you the ability to view and edit a view's size and position based on its alignment rect or its frame rectangle.
Related
I'm going to show you an image that contains my first UIViewController presented in Interface Builder (using the 600x600 Any/Any View).
MainViewController
For now, just look at the UIButton with the C label and the Play button. I added Align center x to: horizontal constraints to both. When I preview what I have (forgetting about the other views and buttons you see), the 2 buttons are centered properly. However, when I switch different device sizes, they do not change size...which makes sense.
What I want is for a way to make those 2 buttons stay proportionally circular and centered on the superview, but adapt their size and Y-position depending on the device size. What constraints would I need to attach in order for that to work? I don't want the buttons to be stuck in the spots you see in the image, I want them to adapt to the device size.
To talk about this further. The game 'Color Switch' does not appear to use constraints in terms of having any view/image/button/label constrained to a certain y or x position. Going from a 5c to a 6s, it's like looking at a blown up version of the game. The buttons and title label at the top are not constrained to the same y position on each device.
You could create constraints to center the buttons to the top-level view and then make their width proportional to the view width. Then on a larger screen, the buttons will be larger and on a smaller screen, they will be smaller.
I have an NSView inside my main view that is preventing my window/main view from resizing correctly. Even when I go fullscreen, My main view can't fill the screen (there's some black space at the right). I know that the cause is that particular view (or something inside) as when I delete it my app behaves normally. What would cause an NSView to "control" growing of its window?
Here are the constraints on that view:
UPDATE: I've found an NSTextField inside which had hugging proiorty set to 750. I've taken it down to 250, now it DOES grow, but I can't shrink it down from "some" size. I'm calling it "some" size because it has nothing special: it's a bit less than my native fullscreen width, and it's different than my IB width.
In general, constraints with priorities higher than NSLayoutPriorityWindowSizeStayPut (500) can force the size of a window. That includes the implicit constraints generated by intrinsic content size, if a view has such, which have the priorities set for content hugging and compression resistance.
So, if you have a text field whose horizontal content hugging priority is, say, 750 and there's a chain of constraints that connect its leading and trailing edges to the window's content view's edges (or, similarly, relate the text field's width to the content view's width), then the window won't be able to grow large enough to "stretch" that text field.
Likewise, if the text field's horizontal compression resistance is high, the window won't be able to shrink to the point where the text field would have to be compressed.
I'm trying to use Auto Layout to minimize the gap between a UIImageView (in green) and a UICollectionView (in red). In the simulator (which I assume is showing an iPhone 4-size screen) the two views line up nicely, with only a small gap between:
However on my actual device, an iPhone 5 with larger screen, there's a big gap:
How can I specify auto layout constraints so that the UIImageView (green box) takes up as much space as available, regardless of screen size, while keeping the UICollectionView pinned to the bottom toolbar?
I've tried experimenting with adjusting the constraints, adding pins, etc in XCode without much success. I feel like I'm just flailing around not really understanding how they work, and I have yet to find a good tutorial that explains how do something like "expand to take up as much vertical space as possible".
So you need to specify that the gap between the two views is fixed, and that the height of the bottom view is also fixed. In visual format language that would be
"V:|[topView]-[bottomView(==150)]|"
V: means this is a vertical constraint
|[topView] means pin the top of topView as close to the top edge of the superview as possible.
- means that the space between the two views is fixed
[bottomView(==150)] means that bottomView must be 150 pixels
]| means that the bottom edge of bottomView is pinned to the bottom edge of the superview
You could also add these constraints in Interface Builder by setting a fixed height on the bottom view, and a fixed gap between the top and bottom views
I'm having resizing issues, and I think it's because I don't really know enough about frames and bounds.
I have a custom view within a scroll view, which fills the window. When I resize the window, I want the custom view to stay where it is, slowly getting covered/uncovered by the window in the place that the mouse is dragging.
What really happens is the custom view stays anchored to the lower left corner of the scroll view, so that if I make the window shorter, the custom view slides up to keep its lower left corner touching the scroll views corner.
How do I resize the window without moving a particular view?
The frame is the area that the view will occupy within its parent. The bounds is the section of the view that will be drawn within its frame. So 99.99% of the time that the two differ at all, they have the same size but the bounds has a zero origin and the frame has a non-zero origin.
That said, it sounds more like you're confused about the coordinate system. OS X follows the graph paper convention of the origin being in the lower left hand edge of the screen. So your scroll view's origin is in the lower left of the window, which results in that point being the anchor when you resize. The size of the scroll view's frame and bounds changes but the origin doesn't.
Assuming you want the top left to be anchored rather than the bottom left (?), possibly the easiest thing to do would be to subclass NSScrollView and override - setFrame: to do appropriate arithmetic — grab the current documentVisibleRect, work out what's in the top left, allow super to set the new frame then call scrollToPoint appropriately.
If you want to pin your document view to the top left, you can override isFlipped in your document view to return YES. In that case the y coordinate will be flipped and you may need to perform some computation adjustments.
- (BOOL)isFlipped
{
return YES;
}
I'm writing a direct3d application and after noticing strange bugs such as anti-aliasing occurring even when it was turned off and the mouse pointer not lining up to things with the same coordinates as itself I discovered that when creating a window the width and height parameters include the border. The program was rendering a 800x600 graphics output to a window of the same size, but because of the borders it was squished into 792x566 rectangle. I've increased the size of the window to compensate, but this does not work if the system uses a border style other the standard XP style. (Classic style, for example)
Is there a way to tell what the border width and heights will be before I create the window?
Another option would be to make sure the D3D surface is the same size as the client rectangle size (GetClientRect()). Then you know you'll render to the appropriate size and not have to worry at all about the width of menus, borders, etc.
It sounds like you are looking for the GetSystemMetrics function. For example, the border width in pixels is returned by
GetSystemMetrics(SM_CXBORDER)
ADDED: For the total size you will need to add together the various "pieces" of the non-client area: border, frame sizes, title bars, etc.