How to keep a CALayer at the same position while resizing the parent NSView? - core-animation

Imagine a small red box (CALayer instance) drawn in the lower left corner of its parent layer (which is the root layer of a layer hosting NSView).
When the frame of the parent view changes, the red box should remain at the same position on the screen. I do this by adjusting it's position relative to the lower left corner of the parent view .
The problem is that in some cases there is flickering and I can see the red box layer being drawn in the lower left corner of the extended frame before it is shown at the correct position.
I assumed that wrapping the frame and position change into one CATransaction would make both changes together, but that doesn't always work (the docs say that by using a transaction the animations will start at the same time, but there still seems to be a race condition at times).
How can I adjust the frame of the parent NSView while keeping the child layer at its perceived position?
Example and code:
My own ideas:
Hide red box layer, update the position, show it again
Use constraints to bind it to the right corner. Problem is that this offset could also change and I would have to update the constraint which could lead to the same flickering issue.

Try deleting the code you have already made to have the layer move with the view and put this where you are creating the layer.
boxLayer.autoresizingMask = kCALayerMaxXMargin | kCALayerMinYMargin;

Related

Move view hiding its side in android

Moving a view I try to hide all parts of view that cross some vertical line, so view starts to loose its width to 0.
The image describes better what I want.
I mean not just shrink a width with scaleX but hide, because this command compresses the photo horizontally, and I need to hide it without distortion.
How can I do it?
On the image a photo started to move left with translationX hiding line by line left side of the photo during this movement. Also, the photo is not at left edge of screen - it's on the center
View has left(and x) attribute in its LayoutParams.
How can I dynamically set the position of view in Android?
When left attribute is negative, it is hidden under the parent view.
If you want an animation, here is the document!
https://developer.android.com/develop/ui/views/animations/reposition-view

Vuejs transition being does not work with child elemenets

I have the following project: https://codesandbox.io/s/vue-template-c1rj1
I expect the image to just come up from the bottom of the screen already being in the middle of the page, but it first comes up from the bottom and then moves to the center of the page. I noticed that setting the width of the notification-box class to 100% fixes it but I am not exactly sure why.
The reason this is not working is because the fixed css property positions an element relative to the parent layer. Usually this is the viewport.
However, the transition property creates a new layer for the the Element it is used on. In your case, Vue applies the transition property during the animation - making the notification-box the next parent-layer (with a width of 0).
Positioning your Image 50% (of 0) left, does not do anything.
Once the animation is over, the transition property disappears, making the viewport once again the next parent layer. Now 50% left (of the viewport) gives you the desired result.

NSStackView / NSScrollView - bisected NSStackview subview?

this is going to be hard to explain.
I am modifying the InfoBarStackView sample code from Apple.
The problem that I am encountering, is that it looks as if one of the subviews is being divided in two, by NSStackview and rendered separately.
In my sample, I am adding 4 subviews to my stack view, each exactly the same size (and same code). This is then placed into an NSScrollView. (The layout is vertical.)
When the application is run, I see the very first two subviews. When I scroll downward, the weirdness begins. The subsequent view is rendered, where the bottom portion is rendered, then the top is rendered. If the vertical size is 272 pixels, the bottom is rendered as 256 pixels and the top is the remainder (16). Scrolling down to the last view causes the same problem.
Attached are some screen grabs to illustrate:
I have a sample project for Xcode 8. I have posted the Xcode 8 project here, if someone would like to take a look. I can't seem to figure this one out.
Are you referring to the extra bounding boxes that intersect the "Label" and "Show" buttons?
If you use Xcode's View Debugger to look at the decomposition of the view hierarchy and the drawn contents of each view, you'll see that the extra bounding boxes are drawn by the GT_BorderedViews — that is, the bottom GT_BorderedViews are each drawing two bounding boxes.
GT_BorderedView's implementation of -drawRect: calculates and draws the bounding boxes based on the dirtyRect that is passed in. However, as the documentation states, the dirty rect is «a rectangle defining the portion of the view that requires redrawing», not necessarily the entire bounds of the view. Changing the implementation to calculate and draw the border based on [self bounds] instead of the dirty rect results in the expected appearance.
Taylor nailed it. I didn't realize that drawRect didn't render the whole view. Using [self bounds] rather than dirtyRect ensures the draw happens properly.

Change size of window in Cocoa?

I have a window whose size I need to change when the user clicks on it. I am using [self setFrame:windowFrame display:YES animate:YES] to accomplish this.
Even though the window successfully changes size (I increase its height), it moves the contents of the window up with it. How do I prevent this from happening? I want the contents to remain in place.
I am on OSX Mountain Lion developing an app for OSX using Objective-C and Cocoa.
EDIT: Constraints and/or Springs and Struts will not work as I need to move the contents around after the window is resized.
Constraints and/or Springs and Struts will not work as I need to move the contents around after the window is resized.
In that case, you should use NSViewAnimation.
A single view animation can actually perform multiple animations to multiple views, and you can even do one to a window, despite the class's name and the fact that windows aren't views in Cocoa.
You create a view animation with initWithViewAnimations:, which takes an array of dictionaries. Each dictionary identifies the target (NSViewAnimationTargetKey) and what to do to it: Either change the target's frame (NSViewAnimationStartFrameKey and NSViewAnimationEndFrameKey) or fade the target in or out (NSViewAnimationEffectKey). For your case, you'll be changing the targets' frames.
When the user does the thing that causes the resize of the window, you'll need to compute the desired overall size of the window (taking care to adjust its frame's position so it doesn't grow off the screen), as well as the new frames—both positions and sizes—of your views. Everything that will move and/or change size, create a dictionary for it and throw it into the array. Then create the view animation.
An NSViewAnimation is a kind of NSAnimation, which provides all the methods for starting and stopping the animation, monitoring its progress, hooking into it, and chaining multiple NSAnimations together. If nothing else, you'll need to start the animation.
If you are using the Interface Builder to build these views, then I believe one approach is to set the "struts and springs." These are available under the "size inspector" and are the red arrows and bars above the "autosizing" label. Play around with these to get the effect that you want, but the general idea is that the arrows control how the size of the view adjusts to changes in the size of the parent view, and the bars control the relationship of the edges of the view to the edges of the parent view as the size changes.
In constraint-based layout, set the views around the edge of your window to be a fixed distance from their superview's edge.
Xcode will infer a lot of resizability from that; if anything still isn't resizing properly, adjust its constraints so that its width and/or height is no longer constant.
The easiest way is to move your views until blue lines show up in the editor. Each blue line corresponds to a rule in the HIG about how things should be lain out, and if you drop the view there, Xcode will create constraints matching those guidelines. For example, if you set a view 20 points from the right edge of its superview, you'll get a blue line for that, and if you drop the view there, you'll create a constraint that the view must remain that distance from that edge.
The superview isn't the only view with which you can create HIG-based constraints. You can also create guideline constraints between sibling views. For example, if you put a button next to another button at the appropriate distance, you'll get a blue line across that distance, and if you drop it, you'll create a constraint that those two buttons must remain that distance from each other.
If you want to do something really custom, the three buttons in the lower-right corner of the nib editor will let you create any constraint you want. What you have selected determines what constraints you can create; the nib editor's outline view will help you make sure you have the selection you want.
You are going to have to iterate through all of your subviews and change their frame positions based on the delta of your window frame.
so if you expand your window frame by 20 in all directions, all your subviews are going to have to increase their frame positions by (20,20) to offset the windows movement.

Programmatically reveal a UIView

I am attempting to reveal (through animation) a UIView. Specifically I want to show the center portion of the view and then slowly reveal the outer edges of it (sort of like pulling back a curtain).
My first attempt was to simply set the bounds rect to be smaller and animate it to be the full size of the view's frame, but this did not have the desired effect since by changing the bounds I was also changing the frame.
If what I am trying to do does not sound possible (at least not in a simple manner), at least I would like to be able to have is some way to make the subviews of the main view stationary relative to the screen, NOT their parent view, as the parent resizes (this would give a similar effect).
Any ideas?
Thank you,
-Matt
It definitely is possible. What you need to do is
For the view you're animating, setAutoresizesSubviews:NO and setClipsToBounds:YES.
Set the view's bounds (NOT the frame) to a rect with zero size and origin at the center point of the rect you want the view to occupy when it is fully revealed (in the view's own coordinate system). In other words, startBounds.origin.x should equal half of endBounds.size.width and similarly for y.
Position the view by setting its center (in the parent view's coordinate system).
In an animation block, change the view's bounds to zero origin and full size.
In the animation's completion block, you probably want to setAutoresizesSubviews:YES again.
You may also need to set the view's autoresizing mask to be fully flexible (springs but no struts), depending on what other layout gets triggered as you resize.
Sounds like you want to change its clipping. A cheap (code-wise) way to do that would be to insert the view into a parent view (with autoresizing set to center it), set the parent to clip its children and then animate the parent's frame.