UIView animateWithDuration doesn't work with Rect width/height animation - ios

The following code works. It animates all those components nicely
CGRect logoRect = self.logoImageView.frame;
CGRect loginBackgroundRect = self.loginControlsBkImageView.frame;
CGRect loginButtonRect = self.loginButton.frame;
CGRect tableViewRect = self.tableView.frame;
CGRect forgotPasswordRect = self.forgotButton.frame;
CGRect signupButtonRect = self.signUpButton.frame;
if (!iPhone) {
// ipad keyboard-on-screen re-layout
logoRect.origin.y-= 60;
loginBackgroundRect.origin.y-= 110;
loginButtonRect.origin.y-=110;
tableViewRect.origin.y-=110;
forgotPasswordRect.origin.y-=110;
signupButtonRect.origin.y-=200;
}
else {
// iphone keyboard-on-screen re-layout
if (portrait) {
logoRect.origin.y-=17;
logoRect.origin.x-=50;
loginBackgroundRect.origin.y-= 70;
loginButtonRect.origin.y-=70;
tableViewRect.origin.y-=70;
forgotPasswordRect.origin.y-=70;
//signupButtonRect.origin.y+=200; // get off screen!
} else {
logoRect.origin.y-= 30;
loginBackgroundRect.origin.y-= 25;
loginButtonRect.origin.y-=25;
tableViewRect.origin.y-=25;
}
}
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^(void) {
self.logoImageView.frame = logoRect;
self.loginControlsBkImageView.frame = loginBackgroundRect;
self.loginButton.frame = loginButtonRect;
self.tableView.frame = tableViewRect;
self.forgotButton.frame = forgotPasswordRect;
self.signUpButton.frame = signupButtonRect;
}
completion:NULL];
Take the following code and add one line (see below) to animate the WIDTH of the logoImageView... and puff... only the logoImageView animation works - the rest simply doesn't move. as if the frame size animation causes everything else not to animate if in the same animation block.
if (portrait) {
logoRect.origin.y-=17;
logoRect.origin.x-=50;
loginBackgroundRect.origin.y-= 70;
loginButtonRect.origin.y-=70;
tableViewRect.origin.y-=70;
forgotPasswordRect.origin.y-=70;
//signupButtonRect.origin.y+=200; // get off screen!
} else {
logoRect.origin.y-= 30;
logoRect.size.width-= 30; // <------- LINE BEING ADDED HERE
loginBackgroundRect.origin.y-= 25;
loginButtonRect.origin.y-=25;
tableViewRect.origin.y-=25;
}
I'm at a loss here. Does anyone know what's going on?

Try to change whole frame, not just width. It should work.
Put these lines before commiting animation (not in block):
self.logoImageView.frame = logoRect;
etc.
And instead of using animate method try to use commit animations this way:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
// Here some more animation settings
// Here your animations
[UIView commitAnimations];

Related

Resizing a UIView hides subviews

I have a view controller with a view that doesn't fill the screen and has transparency around the edges. In said view I have a tableview, some buttons and a text field.
I have all of the controls attached to the bottom of the view with constraints and the tableview attached to the top.
Everything resizes fine when the device is put in landscape/portrait mode, but when I manually resize it when the keyboard appears, the bottom of the view just moves up and covers the lowest elements.
Resizing/animation code:
- (void)keyboardDidShow:(NSNotification *)notification {
//Stuff to get keyboard frames
void (^animations)() = ^() {
CGRect mainViewFrame = self.mainView.frame;
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = tableViewFrame.size.height - 50;
mainViewFrame.size.height = mainViewFrame.size.height - 50;
CGFloat paddingOffset = self.view.frame.size.height - self.mainView.frame.origin.y - self.mainView.frame.size.height;
mainViewFrame.origin.y = (mainViewFrame.origin.y - keyboardEndFrame.size.height + paddingOffset - 8);
self.mainView.frame = mainViewFrame;
[self.tableView setNeedsLayout];
[self.mainView setNeedsLayout];
};
[UIView animateWithDuration:animationDuration
delay:0.0
options:(animationCurve << 16)
animations:animations
completion:^(BOOL finished){
if (finished) {
NSLog(#"Finished animating");
self.acceptBottomConstraint.constant = 5;
self.cancelBottomConstraint.constant = 5;
}
}];
}
This is my UI in the Storyboard:
This is what it looks like after resizing:

UIVisualEffectView blur constraint animation bug

I'm having an issue expanding and contracting a UIEffectView. Its expands fine, but when it contracts it instantly snaps to its final height and slides into position, leaving behind a faint vibrancy effect in its wake. Heres a gif to illustrate the problem.
http://i.imgur.com/Lh8q7m1.gif
This happens in a new blank project setup as so:
Here is the animation code:
- (IBAction)toggleEffects:(id)sender {
[self.view setNeedsLayout];
if(self._effectsHeight.constant == 50){
self._effectsHeight.constant = 500;
}else{
self._effectsHeight.constant = 50;
}
[UIView animateWithDuration:1.5f
animations:^{
[self.view layoutIfNeeded];
}];
}
I think that you have to set the resizing code inside the animation block.Try this way:
[UIView animateWithDuration:1.5f
animations:^{
if(self._effectsHeight.constant == 50){
self._effectsHeight.constant = 500;
}else{
self._effectsHeight.constant = 50;
}
}];

iAd covers my view on the first load

I have iAds working almost perfectly using a modified version of UITabBarController-iAds. The only issue I have is on the very first load of an advert my view gets covered. Once the ad refreshes after 30 seconds the view resizes just fine.
I'm using the following code:
- (void)layoutBanner
{
float height = 0.0;
ADBannerView *_banner = (ADBannerView *)[self.view viewWithTag:12];
CGRect bounds = [UIScreen mainScreen].bounds;
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
_banner.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
} else {
_banner.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
}
//When compiling against iOS 8 SDK this needs to be height, regardless of the actual device orientation
height = bounds.size.height;
CGSize bannerSize = [ADBannerView sizeFromBannerContentSizeIdentifier:_banner.currentContentSizeIdentifier];
//Get content view
UIView *_contentView = self.selectedViewController.view;
CGRect contentFrame = _contentView.frame;
CGRect bannerFrame = _banner.frame;
if (_banner.isBannerLoaded) {
if (iOS7) {
contentFrame.size.height = height - bannerSize.height;
bannerFrame.origin.y = contentFrame.size.height - self.tabBar.frame.size.height;
} else {
contentFrame.size.height = height - self.tabBar.frame.size.height - bannerSize.height;
bannerFrame.origin.y = contentFrame.size.height;
}
} else {
if (iOS7) {
contentFrame.size.height = height;
bannerFrame.origin.y = bounds.size.height;
} else {
contentFrame.size.height = height - self.tabBar.frame.size.height;
bannerFrame.origin.y = bounds.size.height;
}
}
[UIView animateWithDuration:0.25 animations:^{
_banner.frame = bannerFrame;
_contentView.frame = contentFrame;
} completion:^(BOOL finished) {
[self.view bringSubviewToFront:_banner];
}];
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
NSLog(#"Did load");
[self layoutBanner];
}
Any ideas?
I managed to fix this issue by playing around with the animation block. I moved the content view line and it resolved the issue
[UIView animateWithDuration:0.25 animations:^{
_banner.frame = bannerFrame;
} completion:^(BOOL finished) {
_contentView.frame = contentFrame;
[self.view bringSubviewToFront:_banner];
}];
I'm not 100% sure, but I suppose the problem is related to:
[self.view bringSubviewToFront:_banner];
The whole animation:
[UIView animateWithDuration:0.25 animations:^{
_banner.frame = bannerFrame;
_contentView.frame = contentFrame;
} completion:^(BOOL finished) {
[self.view bringSubviewToFront:_banner];
}];
is a little strange, because at the completion block you are bringing the banner view to front, so I can suppose that before animation did start - the banner was covered by some other view or views - what is the reason of frame animation if banner view is covered - thus cannot be seen while animation is in progress?
Of course the issue applies only for the first run.
as of iOs8 [[UIScreen mainScreen]bounds] has changed.. previously it would always return portrait (where H > W ) values, regardless of interfaceOrientation, but it now appears to respect interface orientation... (which is not a bad thing, unless you're taking previous behaviour for granted)
Why don't you try CGRectGetMinY(CGRect aRect) ..
eg. (Im assuming from your code the banner goes along the screen bottom, and your TAbBar across the top. (which I think is weird..) )
//once you have calculated bannerFrame
contentFrame.size.height = ( CGRectGetMinY(bannerFrame) - CGRectGetMinY (contentView.frame) );
contentFrame.origin.y = CGRectGetMaxY(self.tabbar.frame);
Do you have any constraints / resizingMasks set? when you load a second ad the view controller's view has already been resized to fit an ad, presumably the first ad is the one trying to change things..

How to create animation for UIview that needs to pull down to up?

I want to create a screen to pull up from down and need to pull down.like iOS notifications screen (but in reverse direction).Please share if any example is there.Thanks in advance.
The full-on way to do this in iOS 7 is with an interactive custom transition. You will use a UIScreenEdgePanGestureRecognizer and respond to the drag gesture from the edge of the screen by performing part of the transition animation to match the distance the user's finger has travelled. Look into the UIPercentDrivenInteractiveTransition class to help you do that.
Here's a complete example you can download and run: it happens that I'm doing it from the left or right, not the top or bottom, but it is the same basic idea.
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch06p296customAnimation2/ch19p620customAnimation1/AppDelegate.m
But beware: if you try to do it from the top or the bottom you will get interference from the notification center (top) and the control center (bottom). It can be tricky to prevent that interference.
Hi you can use it.
- (void)showShareView {
[self.view bringSubviewToFront:self.view_Email];
[UIView beginAnimations:#"Show"
context:nil];
[UIView setAnimationDuration:0.3F];
CGRect frame = self.view_Email.frame;
if (IS_IPHONE5) {
if(txtFieldActiveFlag==1){
frame.origin.y = 568-420;
}else{
frame.origin.y = 568-220;
}
} else {
frame.origin.y = 480 - 275 - 88;
}
self.view_Email.frame = frame;
[UIView commitAnimations];
}
- (void)hideShareView {
[UIView beginAnimations:#"Show"
context:nil];
[UIView setAnimationDuration:0.3F];
CGRect frame = self.view_Email.frame;
if (IS_IPHONE5) {
if(txtFieldActiveFlag==2){
frame.origin.y = 568-220;
}else{
frame.origin.y = 568;
}
} else {
frame.origin.y = 480;
}
self.view_Email.frame = frame;
[UIView commitAnimations];
}
//call method from any button action.
[self showShareView]; //show the view up
[self hideShareView]; //show the view down
Thanks

Move & Rotate an UIImageView

I have an UIImageView with an rotation animation that loops, I need to move the UIImageView by x and y in the screen.
The rotation animation code is:
-(void)rotate{
if (leftRotate){
leftRotate = NO;
}else{
leftRotate = YES;
}
CGRect initFrame = self.frame;
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse
animations:^{
if (leftRotate){
self.transform = CGAffineTransformRotate(self.transform, -1 * (M_PI/8));
}else{
self.transform = CGAffineTransformRotate(self.transform, M_PI / 8);
}
}
completion:^(BOOL completed) {
if (completed){
if (!stopRotate){
[self rotate];
}
}
}];
}
I try differents approaches to move the image, like setting the center but I cant move it.
I found the way, I have to set the center out side the animation:
CGPoint facePosition = CGPointMake(self.face1.center.x+1,
self.face1.center.y);
self.face1.center = facePosition;

Resources