Animating AutoLayout constrains breaks in iOS 9 - objective-c

So I just upgraded xCode to Version 7.0 (7A220) and it broke some animations, I'm not sure whats wrong here.
[UIView animateWithDuration:SLIDE_UP_DURATION animations:^{
self.cubeIconWhiteYAlignmentToContainerView.constant = actualOffset;
[self.cubeNoIconWhiteImageView layoutIfNeeded];
[self.cubeIconWhiteImmageView layoutIfNeeded];
self.buttonConstraintToBottom.constant = FINAL_BUTTON_HEIGHT;
[self.logInButton layoutIfNeeded];
[self.registerButton layoutIfNeeded];
} completion:^(BOOL finished) {
if (finished) {
[self fadeIn];
}
}];
the buttons slide up just fine but the image views snap to their final height. What am I missing is this just a bug on apples side?

So Apparently both views that the constraint touches need layoutIfNeeded called.

Related

Remove from superview not working in animation completion handler

I have a UIView with several UILabels added. I am simply moving them all to the center of the screen with an animation, and then attempting to remove them from their superview in the animation completion handler.
for (label in [self.view subviews])
{
if([label isKindOfClass:[UILabel class]])
{
CGRect frame = CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/2, label.frame.size.width, label.frame.size.height);
[UIView animateWithDuration:2.0
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
[self->label setFrame:frame];
}
completion:^(BOOL finished){
dispatch_async(dispatch_get_main_queue(),^{
[self->label removeFromSuperview];
});
}
];
}
}
The problem that I am having is that at the end of the animation the UILabels remain. If I put the removeFromSuperView call outside of the animation block then it works, but of course then they are removed before the animation has a chance to complete.
You've got label as the variable in the for-in and self->label in the blocks. Apparently, you weren't operating on the label you thought you were.

iOS7 - Why is CGAffine Transform working properly on iOS8 but not iOS7?

I am having a problem when using CGAffineTransformMakeTranslation on iOS7. The view I am using the CGAffineTransformMakeTranslation is going to a different position when running iOS7 and iOS8. Why is this and what am I doing wrong?
I have a view that I am calling "hud" that is the length of its parentView and 125.0 tall. I am using Auto Layout and here is a screenshot of my story board so you can see how I have the constraints set up. The container view is a collection view of photos.
I have the "hud" hide right away with a transform downward and when a photo is selected it will slide back up into view.
-(void)showHud:(BOOL)show
{
NSLog(#"Frame Height: %f", hud.frame.size.height);
if (show && !hudSelectionMode)
{
[UIView animateWithDuration:0.5 delay:0 options:0
animations:^{
hud.transform = CGAffineTransformMakeTranslation(0, 0);
hud.alpha = 0.8f;
}
completion:^(BOOL finished){
}
];
}
else if (!show && !hudSelectionMode)
{
[UIView animateWithDuration:0.5 delay:0 options:0
animations:^{
hud.transform = CGAffineTransformMakeTranslation(0, hud.frame.size.height);
hud.alpha = 0.8f; // will be 0.0 when not testing
}
completion:^(BOOL finished){
}
];
}
}
Here is the problem
On iOS8 this works flawlessly the hud is hidden from the start and will slide up when an image is selected:
However when running on iOS7 devices the hud is not where I would expect it to be:
If I comment out all the code in -(void)showHud:(BOOL)show the hud will sit at the bottom of the parentView where I would expect it to on both 7 and 8.
On iOS7 you need to multiply the translation value by the scaleFactor of the device. On iOS8 this seems to be done automatically, but not on iOS7.

Animating with Auto Layout and iOS7 jumps to end of animation (fine in iOS6)

I am using Autolayout and animating by changing the constraints, however, in iOS7 the view simply jumps to the end position - in iOS6 I get a nice animation.
Is should be noted these views are UICollectionViews and I have checked the Storyboard and there are no Layout errors.
All I can think is there is something and am or am not setting on the Storyboard or something that I am doing wrong with the Constant settings in the Storyboard.
primaryMenuYContraints.constant = BUTTOMX;;
leftMenuYContraints.constant = 136.0f;
leftMenuBottomConstraint.constant = 5.0f;
[UIView animateWithDuration:0.7f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^
{
// Move in menus
[self.primaryOptionCollection layoutIfNeeded];
[self.menuOptionCollection layoutIfNeeded];
}
completion:^(BOOL finished)
{
}];
I changed to and now works in both iOS7 and 6, still not sure why it does/did it though! I still think I am setting something up wrong in the Storyboard. I am add another view (nothing to do with this lot) programmatically so I believe that is based around frames until I convert it (which I am not doing).
primaryMenuYContraints.constant = BUTTOMX;;
leftMenuYContraints.constant = 136.0f;
leftMenuBottomConstraint.constant = 5.0f;
[UIView animateWithDuration:0.7f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^
{
// Move in menus
[self.view layoutIfNeeded];
}
completion:^(BOOL finished)
{
}];

Fading UIView allows subviews to be seen

I have a UIScrollView which contains various subviews (UIImageViews, UILabels and standard UIViews). Some of the UIImageViews are partially covered by other UIViews.
However, when I fade out the UIScrollView, the partially covered parts of the UIImageViews are being exposed for the brief moment of the animation.
I want to be able to fade the scrollview and all it's contents at the same time in the same animation - i.e. not revealing any of the partially covered images.
If it's not possible, I can always add a UIView on top of all the other controls and fade it from alpha 0 upto 1 to hide everything, but I'm sure there's a way to perform a complete fade on a view and all it's subviews.
I tried this:
[UIView beginAnimations:nil context:NULL];
[scrollViewResults setAlpha:0.0f];
[UIView commitAnimations];
And I've tried this:
- (IBAction)questionGroupChanged:(UIButton*)sender {
[UIView beginAnimations:nil context:NULL];
[self fadeViewHierarchy:scrollViewResults toAlpha:0.0f];
[UIView commitAnimations];
}
- (void)fadeViewHierarchy:(UIView*)parentView toAlpha:(float)alpha {
[parentView setAlpha:alpha];
for (UIView *subView in parentView.subviews) {
[self fadeViewHierarchy:subView toAlpha:alpha];
}
}
But I've still not cracked it. Any ideas?
This happens because of the way the compositor works. You need to enable rasterization on the view's layer when fading it in/out:
view.layer.shouldRasterize = YES;
You should probably only enable this for the duration of the animation because it will take up some extra memory and graphics processing time.
Mike's answer is the correct one and he deserves all credit for this. Just to illustrate, it might look like:
- (void)fadeView:(UIView*)view toAlpha:(CGFloat)alpha
{
view.layer.shouldRasterize = YES;
[UIView animateWithDuration:0.75
animations:^{
view.alpha = alpha;
}
completion:^(BOOL finished){
view.layer.shouldRasterize = NO;
}];
}
Thus, using your scrollViewResults, it would be invoked as:
[self fadeView:scrollViewResults toAlpha:0.0f];
Did you try with UIView class methods +animateWithDuration:* (available on iOS 4 and +)
Like :
- (void)fadeAllViews
{
[UIView animateWithDuration:2
animations:^{
for (UIView *view in allViewsToFade)
view.alpha = 0.0;
}
completion:^(BOOL finished){}
];
}

Simple UIView animation move doesn't work

I have no idea, why it is not working.
All I want to do is a simple UIView animation in the viewDidLoad.
Here's my code:
[UIView animateWithDuration:3.0f animations:^{
[self.headline setCenter:CGPointMake(0.0, 200.0)];
}];
Nothing happens. When I test the general approach of calling a animation method on that particular object like this:
[UIView animateWithDuration:3.0f animations:^{
[self.headline setAlpha:0.0];
}];
it works!!! Why am I not able to move the view across the screen? I am using latest Xcode 4.5.
Thanks for any advice!
UPDATE:
When I add a view manually in code it works. But for the UIViews I create as Outlets in the Interface Builder it doesn't work.
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 100.0)];
testLabel.backgroundColor = [UIColor redColor];
[self.view addSubview:testLabel];
[UIView animateWithDuration:3.0 animations:^{
testLabel.center = CGPointMake(0.0, 200);
}];
So obviously I am doing something wrong in the .xib file
Dont do it in viewDidLoad. The view is not pressent at that time yet.
Try it in viewDidAppear.
Well, I think the reason for the missing animation was the fact that I called a different push navigation animation from the view controller that was pushing the actual view on screen:
- (IBAction)goForSelection:(id)sender
{
SelectionViewController *selectionViewController = [[SelectionViewController alloc] initWithNibName:#"SelectionViewController" bundle:nil];
//[self.navigationController pushViewController:selectionViewController animated:YES];
[UIView transitionWithView:self.navigationController.view duration:1.0 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
[self.navigationController pushViewController:selectionViewController animated:NO];
} completion:^(BOOL finished) {
[selectionViewController startIntroAnimation];
}];
}
First I checked what happens when I use the default navigation controller segue. And to my surprise the animation did start. Then I inserted the call to the [selectionViewController startIntroAnimation] to the completion block and this works as well.