I have this code below who move my UIView to left:
- (void)viewDidLoad {
[super viewDidLoad];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:4];
int xOriginal = 91;
CGRect rect = imagem.frame;
int x = rect.origin.x;
int y = rect.origin.y;
int w = rect.size.width;
int h = rect.size.height;
if(x == xOriginal){
imagem.frame = CGRectMake(x+100, y, w, h);
}else{
imagem.frame = CGRectMake(x-100, y, w, h);
}
[UIView commitAnimations];
}
My coordinate of my view is x = 91 (Center of the superView), When I start my app my UIView start left and go to center, instead of center and go to right, Why this is happening?
How to make my UIView start in center (x=91) and go to right (91+100), instead of left to center?
[UIImageView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
imagem.frame=CGRectMake(imagem.frame.origin.x+100, imagem.frame.origin.y, imagem.frame.size.width, imagem.frame.size.height);
} completion:^(BOOL finished) {
//code for completion
NSLog(#"Animation complete");
}];
Autolayout and frame animations are not good friends. Try to animate constraints instead of directly the frame.
You can create outlets of your constraints, and set the constant property of the constraint in your code to move your views.
You also call -[view layoutIfNeeded] to refresh your constraints while in an animation block.
Else you can remove all of your view constraints and animate its frame fearlessly.
Initially image.frame = CGRectMake(91,100,20,20);
So imageview starting point is 0
[UIView animateWithDuration:5.0
animations:^{
//Animation code goes here
image.frame = CGRectMake(191,100,20,20); //Now imageview moves from 0 to 100
} completion:^(BOOL finished) {
//Code to run once the animation is completed goes here
}];
As the other poster says, you can't animate a view's frame in XIBs/storyboards that use AutoLayout.
Instead you have to animate a constraint that's attached to the view.
What you do is to create a constraint (or multiple constraints) and connect it to an IBOutlet. Then, in your animation code, you calculate the changes to the constraint(s) and change the constant for the appropriate constraints.
For example, if you wanted to shift the vertical position of a view, set up a constraint that sets the vertical position of your view, and link it to an IBOutlet called viewConstraint. Then you'd use code like this:
[myView animateWithDuration: .25
animations: ^
{
viewConstraint.constant -= shiftAmount;
[self.view layoutIfNeeded];
}
];
Related
Within the viewDidLoad method, I create a CGPoint with the min X and Y values from the frame of a view. Then I set the anchorPoint of that views layer to 0,0 and its position to the CGPoint. Then I apply a CGAffineTransformScale to make it 0,0 (hide it.) Whenever a user touches a button I want it to animate from its anchorPoint 0,0 (top-left) to full width and height. If the user presses again animate it to 0,0 . However the view is out of place (from the anchor point change) and whenever I scale it on the button press the pop-up animation is not equal to when the layer is animated to hide. That is whenever the layer is made visible you can see it transition from no width and height to full width and height but when it is made invisible it just disappears.
heres viewWillLayoutSubviews
self.original = CGPointMake(CGRectGetMinX(self.menu.frame), CGRectGetMinY(self.menu.frame));
self.menu.layer.anchorPoint = CGPointMake(0, 0);
self.menu.layer.position = self.original;
self.menu.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0, 0);
This is on button click logic
if(self.isMenuVisible)
{
//hide menu
[UIView animateWithDuration:.5 animations:^{
self.menu.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0, 0);
}];
self.isMenuVisible = NO;
}
else
{
//show it
[UIView animateWithDuration:.5 animations:^{
self.menu.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
}];
self.isMenuVisible = YES;
}
I don't know why zero width and height will cause no animation, but there is a workaround, it is making its width and height scale to 0.01 and when the animation is complete, hide the menu.
if (self.menu.hidden) {
[UIView animateWithDuration:.5 animations:^{
self.menu.hidden = NO ;
self.menu.transform = CGAffineTransformIdentity ;
}] ;
} else {
[UIView animateWithDuration:.5 animations:^{
self.menu.transform = CGAffineTransformScale(self.viewTest.transform, 0.01, 0.01) ;
} completion:^(BOOL finished) {
self.menu.hidden = YES ;
}] ;
}
There is a button that horizontally shifts my table.
- (void)togglePreferencePageVisibility:(id)sender {
int translation = [self preferencesVisible] ? -PREFERENCE_TRANSLATION_HEIGHT : PREFERENCE_TRANSLATION_HEIGHT;
//animate tableview down
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
_table.center = CGPointMake(_table.center.x, _table.center.y+translation);
}
completion:^(BOOL finished){
}];
}
When I call [_table reloadData], the table reverts to its original position. I tried manually readjusting the table position, like so
NSLog(#"before %#", NSStringFromCGRect(_table.frame));
[_table reloadData];
_table.frame = CGRectMake(initialTablePosition.x, initialTablePosition.y+PREFERENCE_TRANSLATION_HEIGHT, _table.frame.size.width, _table.frame.size.height);
NSLog(#"after %#", NSStringFromCGRect(_table.frame));
but no luck. Also the frame's have the same y position before and after.
You need to also adjust the auto layout constraints using the NSLayoutConstraint class. You can add, remove or change the values of NSLayoutConstraints. This is a VERY common question on stack overflow right now, due to the change from iOS 7 to iOS 8.
If you do not adjust the layout constraints then the view will be repositioned back to its original location. reloadData redraws the UITableView which causes the view hierarchy to reexamine its positions e.t.c.
As an example of making a view with a width constraint narrower:
CGRect frame = myView.frame;
frame.size.width -= 100;
//Next line now needed in iOS 8
myWidthConstraint.constant -= 100;
[UIView animateWithDuration:0.5 animations:^{
[myView setFrame:frame];
}];
EDIT: moving back example:
CGRect frame = myView.frame;
frame.size.width += 100;
//Next line now needed in iOS 8
myWidthConstraint.constant += 100;
[UIView animateWithDuration:0.5 animations:^{
[myView setFrame:frame];
}];
When using auto layout, you should not set any frames. If you do, when the view needs to redraw itself, the frame will be reset to the frame defined by its constraints. You should add an IBOutlet to a constraint between your table view and the top (or bottom what ever works for your use) of its superview (I'll call it topCon in the example below).
- (void)togglePreferencePageVisibility:(id)sender {
int translation = [self preferencesVisible] ? -PREFERENCE_TRANSLATION_HEIGHT : PREFERENCE_TRANSLATION_HEIGHT;
//animate tableview down
self.topCon.constant += translation; // this might need to be "-=" depending on whether your constraint is to the top or bottom
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
[self.view layoutIfNeeded];
}
completion:^(BOOL finished){
}];
}
When I rotate the iPad, all the animated components (e.g. views/buttons) will go back to their original position as to when it was first loaded. Is there any way to prevent this?
Here is how I animate object when I click an button e.g.
- (IBAction)button1Pressed:(id)sender{
[UIView animateWithDuration:ANIMATION_SPEED
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
self.view.userInteractionEnabled = NO;
_button1.center = CGPointMake(73.01, 419.0);
_button2.center = CGPointMake(750.0, 419.0);
_button3.center = CGPointMake(850.0, 419.0);
_button4.center = CGPointMake(950.0, 419.0);
CGRect theFrame = _loginView.frame;
theFrame.size.width = 576.f;
_View1.frame = theFrame;
_View2.frame = CGRectMake(_button2.center.x + 44.0, _button2.center.y / 2 - 89.0, 0.0, 597.0);
_View3.frame = CGRectMake(_button3.center.x + 44.0, _button3.center.y / 2 - 89.0, 0.0, 597.0);
_4View.frame = CGRectMake(_button4.center.x + 44.0, _button4.center.y / 2 - 89.0, 0.0, 597.0);
}
completion:^(BOOL finished){
self.view.userInteractionEnabled = YES;
}];
}
I'm still quite new so all the details will be appreciated :)
I suggest you to create constraints for the interface you want to animate. Then add reference to your header file for those constraints as for any view element.
When you want to animate a view, you now have to update its constraints and ask to layout the views.
[UIView animateWithDuration:0.2
animations:^{
//in this case, I add 44 to my button Y position, so it will goes down 44px
buttonYConstraint.constant += 44;
[self.view layoutIfNeeded];
}
]
//Now don't forget to update constraints
[self.view updateConstraints];
Turning off auto layout located under the 'Interface builder document' fixed this in quick fashion :)
I have a UIView at the bottom left of its superview, i.e.its frame is like
[myView setFrame:CGRectMake(0,superView.bounds.size.height-myViewHeight,myViewWidth,myViewHeight)];
I want to animate its size such that its bottom left point remains fixed at its position. I am not sure how to play with anchor point property of layers.
Currently I am increasing its size using the following lines of code.
[UIView animateWithDuration:0.2 animations:^{
[bottomLbl setFrame:CGRectMake(0, bottomView.bounds.size.height-250, 300, 250)];
This works fine but when I try to bring back to its original size, its bottom point gets lifted at the start of animation and settles down at the end of animation.
First define the point for the bottom left corner...
CGPoint bottomLeft = CGPointMake(0, 480); // this can be anything.
Then you need to define the sizes (big and small).
CGSize bigSize = CGSizeMake(280, 280);
CGSize smallSize = CGSizeMake(50, 50); // again, these can be anything.
Then animate them...
// create the rect for the frame
CGRect bigFrame = CGRectMake(bottomLeft.x, bottomLeft.y - bigSize.height, bigSize.width, bigSize.height);
CGRect smallFrame = CGRectMake(bottomLeft.x, bottomLeft.y - smallSize.height, smallSize.width, smallSize.height);
[UIView animateWithDuration:0.2
animations:^{
// set the rect onto the view
bottomLbl.frame = bigFrame;
// or
bottomLbl.frame = smallFrame;
}];
As long as you set the frame and the calculated end frames are correct and it's all done in one animation then the bottom left corner won't move.
If this doesn't help can you please post a video of what is happening (and all your animation code).
EDIT
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
// set the rect onto the view
bottomLbl.frame = bigFrame;
// or
bottomLbl.frame = smallFrame;
}
completion:nil];
I want to lengthen the right search bar 20 px to the left, and shorten left search bar 20 px to the right with animation. How can I do that?
CGRect leftFrame = self.leftSearchBar.frame;
//leftFrame.origin.x = leftFrame.origin.x - 20;
leftFrame.size.width = leftFrame.size.width - 40;
CGRect rightFrame = self.rightSearchBar.frame;
rightFrame.origin.x = rightFrame.origin.x - 40;
rightFrame.size.width = rightFrame.size.width + 40;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.leftSearchBar.frame = leftFrame;
self.rightSearchBar.frame = rightFrame;
[UIView commitAnimations];
It doesn't work. It first resizes views without animation, then moves the right view with animation.
Assuming you've not changed the anchor points, or anything like that, simply expanding the width will make it stretch to the right. Wrap this within a UIView animation block, and it should animate according to the specification within the question, as so:
UISearchBar* searchbar = ...; // However you've created your UISearchBar, we'll refer to it as 'searchbar'
CGRect searchFrame = searchbar.frame;
[UIView animateWithDuration:0.8
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
searchFrame.size.width += 30;
searchbar.frame = searchFrame;
}
completion:nil];
You'll need to make sure the += 30 doesn't get called more than once, as otherwise you'll be expanding by 30 points each time this is called. If you know the size before hand, you could simply substitute it with = size + 30, which is a safer bet incase you call the animation more than once.