I have an imageview I put onto the view controller of a circle.
I would like to start that circle from off screen and move it to the location I've put it.
What would be the best way to animate it?
Try this;
-(void)viewWillAppear {
[UIView animateWithDuration:5
delay:5
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGRect frame = view.frame;
frame.origin.y = self.view.frame.size.height-200;
frame.origin.x = 0;
view.frame = frame;
}completion:^(BOOL finished) {}];
}
You many animation option's [UIViewAnimationOptions]
UIViewAnimationOptionCurveEaseInOut,
UIViewAnimationOptionCurveLinear,
UIViewAnimationOptionTransitionFlipFromLeft,
UIViewAnimationOptionTransitionCurlUp,
UIViewAnimationOptionTransitionCrossDissolve,
UIViewAnimationOptionTransitionFlipFromTop..
You want to create your image view off-screen. Its easiest if you set it up in Interface Builder that way. you can create it on-screen, add a constraint to place it at the target location, note the value, and then change the constraint's constant so the view is moved off-screen.
Then control-drag the constraint into your view controller and create an outlet to it.
To animate the image view on-screen, change the constraint's constant value to the "on-screen" value you noted above, and then call layoutIfNeeded() on the view from inside an a UIView animateWithDuration block.
If you want to add the image view in code then you need to add it off-screen, add it as a subview, and then trigger a UIView animation to move it back on-screen. You should probably also do the positioning with constraints as outlined above, although it gets more complicated because you have to create those constraints in code.
Related
I want to change my width constraint of View. I have connected the width with IBOutlet inside my View Controller. However, it does not work.
Try to animate it what's going on, actually the View keep going back to its original position.
Here is the code:
_providerExpSearchInputWidth.constant = 1000.0f;
[_providerExpSearchInput layoutIfNeeded];
Anyone can advise?
You should have your view tell autolayout to layout its subviews immediately first so that your layout constraints are completely known. Then you should set a new constraint and in your animation block you will again tell autolayout to layout its subviews immediately. Since you're making this call in the animation block, all of the changes will be animated.
You can try something like this:
[self.view layoutIfNeeded];
_providerExpSearchInputWidth.constant = 1000.0f;
[UIView animateWithDuration:4.0 animations:^{
[self.view layoutIfNeeded];
}];
This is from the Apple Documentation on layoutIfNeeded:
Use this method to force the layout of subviews before drawing. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root.
I have a UIView called containerView.
I add this as a subview to a controller view's root view. I have programmatically added a few constraints to it (I centered it and made the width a few points from the superview's width).
I have added a few UILabels to the containerView as subviews. The height of the UILabels dictate the height of the containerView.
When the user taps the screen, the containerView is moved up from CGRectOffset() and once the animation is complete, it is moved back to the original position.
CGPoint absolutePoint = self.containterView.frame.origin;
self.containerYConstraint.constant = -absolutePoint;
[UIView
animateWithDuration:0.5
animations:^
{
[viewForUpdate setNeedsUpdateConstraints];
}
completion:^(BOOL finished)
{
self.containerYConstraint.constant = 0;
[viewForUpdate setNeedsUpdateConstraints];
[self.containerView.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)]; // Remove all subviews
}];
I need to remove the UILabels I have put in there as subviews and replace them with different labels. However, the moment I remove one of the UILabel's the entire containerView goes missing (I set the background as red so I can see it). I remove all the subviews in the example but when I try to just remove one the same effect occurs.
Why does this occur? Does this have something to do with auto layout? Also if I want to recenter it after I remove one of the UILabels, how do I re-do the constraints?
Modifying frames when using AutoLayout is a no-no. Once you begin using AutoLayout you're effectively telling the system that you want it to set the frames for you.
Instead of animating the frame directly, create properties pointing to your constraints and animate those constraints.
I have a button and on click event of it i want to insert a UIView. I know how to insert a UIView however i am not able to push/move other UIView's that are below it so that i can accommodate the added UIView.
I have already looked at this link but it does not serve my purpose
Any suggestions?
In the method of the button create the new view and add it as a subview. Set the frame.origin.x to 0 minus the width of the view (if you want it to push from the left) so it is not visible and change that value to where you want it to be inside [UIView animateWithDuration:animations:].
[UIView animateWithDuration:1.0 animations:^(void){
[newView setFrame:({
CGRect frame = newView.frame;
frame.origin.x = 150; // If you want it to start at x = 150
frame;
})];
// If you want to move other views too, just add them in this block
}];
If you don't get what I'm doing to set the frame, check out the first tip in this post.
When I add some animations on the subview of the scrollview that like extending or contract a textfield,it just not work. But it worked well when the subview add to a simple UIView.
How did it happen?
There should be no problem animating the frame of a UITextField within a UIScrollView.
The most common source of "my animation isn't animating" in iOS 6 and later is the attempt to animate a control by adjusting the frame when employing autolayout (because the adjustment of the frame can be thwarted by the constraints being reapplied by the most innocuous of actions). You can tell if you're using autolayout or not by selecting the File Inspector (the first tab) of the rightmost panel in Interface Builder, and seeing if "Use Autolayout" is checked:
For example, to animate the frame when not using autolayout, assuming your UITextField has an IBOutlet called textField, you might do something like:
[UIView animateWithDuration:0.5 animations:^{
CGRect frame = self.textField.frame;
frame.size.width = 280;
self.textField.frame = frame;
}];
But the equivalent when using autolayout is not achieved by adjusting the frame, but rather by changing the constraints' constant values. For example, assuming you created an IBOutlet for the width constraint called textFieldWidthConstraint on your UITextField, you would animate the changing of the width with something like:
self.textFieldWidthConstraint.constant = 280;
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
If you believe you are using the appropriate animation technique that corresponds to your choice of autolayout or non-autolayout, but it's still not working, you should show us some code and describe the situation in greater detail.
I've never worked with autolayout constraints before. I have a small new app I'm working on and noticed that the NIB's views are defaulting to autolayout. So, I figured I'd take the opportunity to work with it and try to figure out where Apple is going with this.
First challenge:
I need to resize an MKMapView and I'd like to animate it to the new position. If I do this the way I'm used to:
[UIView animateWithDuration:1.2f
animations:^{
CGRect theFrame = worldView.frame;
CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170);
worldView.frame = newFrame;
}];
...then the MKMapView will 'snap' back to its original height whenever a sibling view gets updated (in my case a UISegmentedControl's title is being updated [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]).
So, what I think I want to do is change the constraints of the MKMapView from being equal to the parent view's hight to being relative to the top of the UISegmentedControl that it was covering: V:[MKMapView]-(16)-[UISegmentedControl]
What I want is for the MKMapView height to shorten so that some controls beneath the map view are revealed. To do so I think I need to change the constraint from a fixed full size view to one where the bottom is constrained to the top of a UISegmentedControl...and I'd like it to animate as view shrinks to new size.
How does one go about this?
Edit - this animation is not animating though the bottom of the view does move up 170 instantly:
[UIView animateWithDuration:1.2f
animations:^{
self.nibMapViewConstraint.constant = -170;
}];
and the nibMapViewConstraint is wired up in IB to the bottom Vertical Space constraint.
After updating your constraint:
[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];
Replace self.view with a reference to the containing view.
This works for me (Both iOS7 and iOS8+). Click on the auto layout constraint you would like to adjust (in interface builder e.g top constraint). Next make this an IBOutlet;
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;
Animate upwards;
self.topConstraint.constant = -100;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
Animate back to original place
self.topConstraint.constant = 0;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
There is a very good tutorial from apple itself that explain how to use animation with autolayout.
Follow this link and then find the video named "Auto layout by example"
It gives some interesting stuff about autolayout and the last part is about how to use animation.
I have made this small demo available. It shows how auto-layout constraints can be changed and animated in a very simple example. Simply take a look at the DemoViewController.m.
Most people use autolayout to layout items on their views and modify the layout constrains to create animations.
An easy way to do this without a lot of code is creating the UIView you want to animate in Storyboard and then creating a hidden UIView where you want the UIView to end. You can use the preview in xcode to make sure both UIViews are where you want them to be. After that, hide the ending UIView and swap the layout constraints.
There is a podfile for swapping layout constrains called SBP if you don't want to write it yourself.
Here's a tutorial.
No need to use more IBOutlet reference of the constraint instead of this you can directly access or update already applied constraint either applied by Programmatically or from Interface Builder on any view using the KVConstraintExtensionsMaster library. This library is also managing the Cumulative behavior of NSLayoutConstraint.
To add Height Constraint on containerView
CGFloat height = 200;
[self.containerView applyHeightConstrain:height];
To update Height Constraint of containerView with animation
[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
if (expectedConstraint) {
expectedConstraint.constant = 100;
/* for the animation */
[self.containerView updateModifyConstraintsWithAnimation:NULL];
}
}];