Setting the frame to a UIView not working - ios

I need a UIView to be hidden from the screen initially and then slides up. Kind of like a UIActionSheetView animation. In IB, I have set a UIView stick to the bottom border of the superview. In code, I have changed its frame to be hidden away from the screen when the app starts. And when it starts, the UIView slides up. Here's is my code. This optionsSheetView is the 'UIView' I'm referring to.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Hide the UIView from the screen initially
self.optionsSheetView.frame = CGRectMake(0, self.optionsSheetView.frame.origin.y + self.optionsSheetView.frame.size.height, self.optionsSheetView.frame.size.width, self.optionsSheetView.frame.size.height);
// Sliding up animation
[UIView animateWithDuration:0.9 delay:0.5 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.optionsSheetView.frame = CGRectMake(0, 374, self.optionsSheetView.frame.size.width, self.optionsSheetView.frame.size.height);
} completion:^(BOOL finished) {
}];
}
Now here's my problem. This works just fine. But I don't like keeping hard coded values in my code. Like 374 for the optionsSheetView's y coordinate. If I put self.optionsSheetView.frame.origin.y there, it won't work. It's basically the same thing. When I replace it with its actual value which is 374, it works fine.
Why is this happening? Is there any way I can go about this without using magic numbers?
Thank you.

Try following:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGFloat oldY = self.optionsSheetView.frame.origin.y;
// Hide the UIView from the screen initially
self.optionsSheetView.frame = CGRectMake(0, self.optionsSheetView.frame.origin.y + self.optionsSheetView.frame.size.height, self.optionsSheetView.frame.size.width, self.optionsSheetView.frame.size.height);
// Sliding up animation
[UIView animateWithDuration:0.9 delay:0.5 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.optionsSheetView.frame = CGRectMake(0, oldY, self.optionsSheetView.frame.size.width, self.optionsSheetView.frame.size.height);
} completion:^(BOOL finished) {
}];
}

Related

UIView doesn't animate

I want to animate the center of a UIView, and I did this in viewDidLoad:
_test.center = CGPointMake(100.0,100.0);
[UIView animateWithDuration:10.0
delay:5
options:UIViewAnimationOptionCurveLinear
animations:^{_test.center = CGPointMake(100.0,-100.0);}
completion:^(BOOL finished) {
}];
But when I run the code, the center of test view is already at 100,-100. Why it doesn't animate?
Move the code from your viewDidLoad to your viewDidAppear. In viewDidLoad, the UIView has been loaded, but it is not visually present yet.
I guess you are using auto constraints which prevent animating views the way you are doing.
In order to fix this issue try these steps:
First:
Move your code to - (void)viewDidLayoutSubviews.
Second:
Do these steps before and after doing any animation to your view:
- (void)viewDidLayoutSubviews{
_test.translatesAutoresizingMaskIntoConstraints = YES;
_test.center = CGPointMake(100.0,100.0);
[UIView animateWithDuration:10.0
delay:5
options:UIViewAnimationOptionCurveLinear
animations:^{_test.center = CGPointMake(100.0,-100.0);}
completion:^(BOOL finished) {
}];
[_test updateConstraints];
}

Animate view moving up on launch

I have a UIImageView which is centred horizontally and vertically in the launch screen. I want to display the same logo on the main storyboard (main view controller) when the launch screen goes, centred horizontally but at the top of the screen.
I have added the same image view to my main storyboard in the same position and added the following code to animate the image from centre to top of screen.
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self animateLogo];
}
- (void)animateLogo {
[UIView animateWithDuration:1 animations:^(void){
CGRect currentFrame = self.logoView.frame;
self.logoView.frame = CGRectMake(currentFrame.origin.x, self.view.frame.size.height, currentFrame.size.width, currentFrame.size.height);
}];
}
#end
However instead of seeing the animation move up, I see it move down from the top to centre.
Can someone point me in the right direction to fix this?
You should animate constraint instead frame:
- (void) viewDidAppear:(BOOL)animated {
self.topConstraint.constant = (self.view.frame.size.height - self.viewToAnimate.frame.size.height) / 2;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
}

UIView automatically moving by uitextfield keyboard

So i have a really weird problem at my hands and hours of search has provided nothing.
I have a uiview containing a uitextfield. Now initially this view is outside of the visible screen with coordinates like x=-500,y=-500.
However in response to a button press this view animates and moves into the center of the screen.
Now whenever i tap on a uitextfield that is the subview of this view.This view moves back to its original coordinates outside the screen.
I have frantically checked my code and there is nothing that is moving the view outside again once its in. Any help in explaining this very unfamiliar behaviour would be really appreciated.
This code moves the view onto the screen
- (IBAction)Register:(id)sender {
//(self.view.frame.size.width/2)-(self.SignUp_Screen.frame.size.width/2);
//self.login_Screen.hidden = YES;
self.blurView.hidden = NO;
//self.SignUp_Screen.layer.zPosition = 5;
NSLog(#"Register");
self.SignUp_Screen.hidden = NO;
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.SignUp_Screen.frame = CGRectMake(35, 50,self.SignUp_Screen.frame.size.width , self.SignUp_Screen.frame.size.height);
} completion:^(BOOL finished) {
}];
}
and these are the delegate methods for the textfield
-(void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(#"TextFieldEndEditing");
[textField resignFirstResponder];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(#"textFieldShouldReturn");
[textField resignFirstResponder];
return YES;
}
As Wezly hints at, if you are using autolayout, you don't modify the frame directly anymore. That's the old world. You want to have an Outlet / property for the constraint and animate it.
[UIView animateWithDuration:0.25
animations:^{
SignUp_Screen.centerXConstraint.constant = ...;
SignUp_Screen.centerYConstraint.constant = ...;
[SignUp_Screen layoutIfNeeded];
}];
See here and here for more details.
You should not modify frame if you are using auto layout. You should animate view by animating constraint's constant. For example:
NSLayoutConstraint *viewY; //constraint from superview top to view top
viewY.constant = 100;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.3f animations:^{
[self.view layoutIfNeeded];
}];
The way i solved this problem was by linking an IBOutlet to the constraint I wanted to change and then animating it's constant value.
.h
#interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *constraintHandle;
}
.m
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
constraintHandle.constant = self.view.center.x;
[SignUp_Screen layoutIfNeeded];
} completion:^(BOOL finished) {
}];
Don't forget to link the IBOutlet to your constraint in your storyboard or xib.

UIView transform work strange

I use this code to move my view
[UIView animateWithDuration:0.3 animations:^{
[MyView setTransform:CGAffineTransformMakeTranslation(260, 0)];
} completion:^(BOOL finished) {
}];
MyView is a subview of self.view
I want to move it to right with 260
but it will first move to left with 130 and no animate
and then move to right with 260 and animate
I don't know why MyView move to left first?
The problem is that you are using auto layout. For a simple animation, trying turning off auto layout in storyboard.
Your animation should work then as expected.
I guess the problem is that the MakeTranslation function is making your view reset it's position before animating to the new transform.
Try this:
[UIView animateWithDuration:0.3 animations:^{
[MyView setTransform:CGAffineTransformTranslate(myView.transform, 260, 0)];
} completion:^(BOOL finished) {
}];

animateWithDuration setFrame not working

Hi I have piece of code which only one line is not working...
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[label setFrame:CGRectMake(0, 0, frame.size.width, kStandardLabelHeight)]; //working
[self.currentLabel setFrame:CGRectOffset(self.currentLabel.frame, frame.size.width, 0)]; //not working
[self.currentLabel setAlpha:0.0f]; //working
} completion:^(BOOL finished) {
[self.currentLabel removeFromSuperview];
self.currentLabel = label;
}];
I'm running out of ideas what is wrong...
What I find out is: if I turn off "Use Auto Layout", then it magically working, so this issue is connected with auto layout.
After a search, I find this: http://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-was
Add constraint outlet mapping for your view, then instead of using setFrame, updating constraints will do the trick!
Below is my final implementation (_topConstraint is the top vertical space constraint of table view):
- (IBAction)switchButtonTouched:(id)sender
{
if (_topConstraint.constant <= 0)
_topConstraint.constant = _buttonView.frame.size.height;
else
_topConstraint.constant = 0;
[_tableView setNeedsUpdateConstraints];
[UIView animateWithDuration:0.5f animations:^(void){
[_tableView layoutIfNeeded];
} completion:^(BOOL finished){
}];
}
Frame must be a CGRect with 4 parameters: (xPosition,yPosition,width,height). Use CGRectMake for set frame
self.currentLabel.frame = CGRectMake(100, 100, self.currentLabel.frame.size.width, self.currentLabel.frame.size.height)
You set 0.3 sec the animation duration, and when it s end you remove it from the view. This is too short. set the duration for example 2, and you will see that your label is moving .
Sometimes you should set frames for animating views also after animation, for example in completion block, try something like that
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[label setFrame:CGRectMake(0, 0, frame.size.width, kStandardLabelHeight)]; //working
[self.currentLabel setFrame:CGRectOffset(self.currentLabel.frame, frame.size.width, 0)]; //not working
[self.currentLabel setAlpha:0.0f]; //working
} completion:^(BOOL finished) {
self.frame = currentLabelFrame;
label.frame = label.frame;
[self.currentLabel removeFromSuperview];
self.currentLabel = label;
}];
If your issue is neither Autolayout related, or the others listed here, there is also another possible problem that turned out to be my issue. I'm simultaneously running a UIView transition (transitionFromView:toView:) on views that take up the same screen space (Different superviews, not related, other than positioning in the superview of the overarching view controller).
My code looked like this:
[UIView transitionFromView:self.someView
toView:self.someOtherView
duration:0.6f
options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionShowHideTransitionViews
completion:NULL];
[UIView animateWithDuration:0.3
delay:0.0 options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self.someThirdView setFrame:someFrame]; //not working
[self.someThirdView setAlpha:1.0f]; //working
} completion:nil];
The frame changed, but it popped to the new frame rather than animating. I'm guessing this is an internal iOS issue. As soon as I removed the "transitionFromView:..." call, the frame animation worked fine.
My solution for now has been to move the second animation into the completion block of the transitionFromView. It's not perfect, as the two animations should have lined up, but it is a passable solution for now.

Resources