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;
}
Related
I've been messing around with UI Automation and Scrolling. I found that in notepad if you take the bounding rectangle of the scrollable window, subtract out the size of any scrollbar bounding rectangles, it scrolls perfectly. However, trying the same thing against ISpy++, which aligns the top treeview item perfectly on each scroll even when there may be one or two pixels of the next item in the view at the bottom.
The problem with that is it reports the scroll amount requested was set. Say the view was 6.384914% and you do all the math to calculate where you scroll the view to the next window, say it came out to 24.382102 (completely made up number), so you scroll there, but it really didn't because it aligned the top item which otherwise would be missing a few pixels based on height of window. You read back where scrolling decided to set it and it says it was 24.382102 (note that when the scroll actually moves a full item it does report a different final scroll position and so can be calculated out).
What would solve the above is if we knew the actual bounding rectangle of the view that represents the 6.384914% so that those extra pixels wouldn't be considered part of the view, when you move to the next page, you're now align to where the next page would actually start. In this case of the tree, the bounding rectangle would be aligned to all items that fit plus the final spacing (or that could be part of the top of the view).
I wanted to scroll and get the data perfectly without any overlaps (except on final page of course, but that could be calculated out when you have the proper aligned boundaries that matches scrolling) or extra spacing.
Is there a way to do that, that I'm missing?
TIA!!
How to make sure views do not get clipped when window is resized and the size of views become smaller or bigger with the window size? Is there a way to do this other than using an autoresizing mask?
The views in a window i have are getting clipped if the window is made smaller, i want the size of the views to decrease with the decrease in window size. How can this be done using constraints?
You should constrain the views to your window edges (their topmost superview in the hierarchy).
First you click and drag holding Ctrl from your view to the content view of the view controller (or window controller):
Then you make the required constraints so that your views are not clipped (those would be trailing, leading, top and bottom constraints):
I have an NSSplitView with content in both NSViews. The left NSView has 2 constraints – Equal Widths and Equal Heights. The right NSView has something simple, say an NSTextField, which is centered via constraints Center X Alignment and Center Y Alighment. This is what I hoped it would look like as I resize the window and/or the NSSplitView divider:
This is what's happening:
I've tried a great deal of configuration changes, I've tried using an NSSplitViewController vs just dropping an NSSplitView into an NSViewController to adjust more parameters programmatically, but I'm not having any luck. Whenever resizing the window, the left view always takes over the excess space. The same happens with the divider (it can be resized, but letting go of the mouse button causes it to snap right back). It seems there's something fundamental that I'm missing here.
The text field's content hugging priority is probably higher than the split view item's holding priority. Fix that and the view should probably work the way you expect.
Also, if, when you resize the view, the left view is resizing with the window while the right view stays the same size, then that suggests that the left view's holding priority may be higher than the right's. You should make the side that you want to stay the same size have the higher holding priority.
That said, I'm not sure what you mean about the constraints you've set on the subviews. "The left NSView has 2 constraints – Equal Widths and Equal Heights." What do you mean here? Its width is equal to what? Its height is equal to what? Do you mean it has an aspect ratio constraint? Frankly, I can't think of what constraints of those kinds would make sense for a view within a split view.
so i have a uiview that is initialized with a frame that has the height and width that is present for the user, i want the user to be able to draw inside this frame but when the user presses a button, i want the view to cut off that extra wasted space so that the frame is only as big as what the user was drawing. I tried to do something like this
CGRect boundbox = CGPathGetBoundingBox([myPath CGPath]);
boundbox.origin.x = self.frame.origin.x;
boundbox.origin.y = self.frame.origin.y;
self.frame = boundbox;
However, this does not remove that extra wasted space, it only resizes the view, so that the drawn content looks smaller than previously. What i would like to do instead is to remove
that "whitespace", i was thinking if it could be possible to scale up the content of the uiview, but im not sure.
To clarify what i mean:
The red border is the area / frame that the user can draw on, the text in the middle is a drawing, when the user presses a button, i want the frame to only encircle the drawing like in figure 2.
Now lets say i have the following scenario, i have drawn a circle on the middle of the screen.
When i then press the button, the scale remains the same but the circle is still in the same position but we have now changed the draw area, so the circle / drawing will look like its cut off like in figure 4.
What i want to do is to move the drawing / bezier path so that it is positioned in the middle of the frame. So that the red area encircles the blue circle.
[EDIT]
Given your drawings. A UIView will not re-position items in it when you change it's frame property (or it's CGRect). In this case you will need to track the items drawn YOURSELF, and then when the button is pressed perform the object translations yourself.
What that means is you will have to find the object that is left most, the object that is topmost, then move all objects left by that amount, and up by that amount so that all objects are (as a grouping) top-left aligned within the view's frame. After this you will need to self recognize which object is the right most touching and which object is the bottom most touching.
NOW, since you have already moved the items left-top, the right most point will define your frame width, and the bottom most point will define your frame height.
IF YOU SO DESIRE, you should be able to zoom in using the properties below after you have done this.
[First Answer]
If I understand your question correctly, you may want to still perform your box frame manipulation, but if you wish to scale you may want to look into the
contentScaleFactor or
contentStretch
properties.
contentScaleFactor should scale both dimensions based upon a singular floating point value (i.e. xWidth * scaleFactor, yHeight * scale factor).
contentStretch is a CGRect which means that it should scale each dimension (axis) separately.
I put a bunch of objects into a UIScrollView and I no have a problem: When I try to "scroll" to some off-screen objects, they appear so long as I am holding my finger down after dragging it, but when I let you, the UIScrollView snaps back to the original position.
Is there a way to prevent this? No off-screen gray area is appaering when this happens, BTW.
Thanks.
You have to set the scroll view's contentSize to include your objects, so it knows how large the scrollable area is — how far to scroll freely before it hits the edge and bounces back.
Try adding a Content Size Fitter component to the Scroll View's Content object and set its scroll direction (Horizontal Fit or Vertical Fit) to Preferred Size.