I need to set the position of UIView. The code below shows how I do it. But it does not work. How do I do this?
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame = myview.frame;
frame.origin.x = myview.frame.origin.x;
frame.origin.y = 0;
myview.frame = frame;
NSLog(#"%d", frame.origin.y );
}
UIView's have a center property..if you want to change the position then just use that... rather to resize whole view
myview.center = CGPointMake(50, 250);
Hope it helps you.
Make sure that your OUTLET is connected to your view in the nib file.
Try to do this in viewDidAppear method,it works for me.
Move view/ change the position of view with animation
if you want to change the position of View as you want then just use following lines of code :
.h file :
- (void)moveView:(UIView *)view withDuration:(NSTimeInterval)duration
andCurve:(int)curve inDirection_X:(CGFloat)x inDirection_Y:(CGFloat)y;
.m file :
- (void)moveView:(UIView *)view withDuration:(NSTimeInterval)duration
andCurve:(int)curve inDirection_X:(CGFloat)x inDirection_Y:(CGFloat)y
{
// Setup the animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:YES];
// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
view.transform = transform;
// Commit the changes
[UIView commitAnimations];
}
Note : To call above method anywhere just do like it ,
As per your requirement i.e. how to move view/ change the position of view with animation
[self moveView:mFrontSideView withDuration:2.0 andCurve:0 inDirection_X: 0.0 inDirection_Y: mBackSideView.center.y + 100.0];
Related
I have a simple animation that moves a slide up and down repeatedly. Here is the code:
CGRect frm_down = slider.frame;
frm_down.origin.y += 50;
[UIView animateWithDuration:0.7
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
slider.frame = frm_down;
}
completion:NULL];
This is pretty straight forward and works great; however, when I am presenting the view (self presentViewController:animated:) the animation does not happen.
In fact, the slider is INSTANTLY moved to the lower position (as if it called the animation only once and moved it back down, but not back up).
I have also tried this:
CGRect frm_down = [[[slider layer] presentationLayer] frame]
This will keep the slider in its original position instead of moving down once, and the animation still does not happen.
Any idea what I am missing? Thanks!
Your animation works. I tested it.
What you need is:
Instead of using:
self presentViewController:animated:
Use this:
[self addChildViewController:<YOUR_VIEWCONTROLLER>];
[self.view addSubview:<YOUR_VIEWCONTROLER>.view];
[<YOUR_VIEWCONTROLER> didMoveToParentViewController:self];
Addendum:
In your view controller's viewDidAppear, add the following code:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGRect frm_down = self.view.frame;
frm_down.origin.y += 50;
[UIView animateWithDuration:0.7
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
self.view.frame = frm_down;
}
completion:NULL];
}
It will animate when it comes into view.
I ran it as a test a priori. Hope it helps.
On Swift :
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
var from_down = self.view.frame
from_down.origin.y += 50
UIView.animate(withDuration: 0.2, delay: 0.0, options: .autoreverse, animations: {
self.view.frame = from_down
}, completion: nil)
}
In my app I have a scrollview and when I press a button it is hidden when I press again it shows up.
I use scrollview.hidden = YES (or NO) to do it.
But I want to do it with an animation. For example, it may disappear from the bottom of the screen by moving and shows up with the same way. How can I do that?
edit:
[UIView beginAnimations:#"myAnimation" context:nil];
CGRect Frame = bottomScroller.frame;
if(Frame.origin.y == 380){
Frame.origin.y = 460;
}else{
Frame.origin.y = 380;
}
bottomScroller.frame = Frame;
[UIView commitAnimations];
This solved my problem...
You may check UIView animations. It's pretty easy. For example to animate translation you may use something like:
[UIView beginAnimations:#"myAnimation" context:nil];
CGRect Frame = yourView.frame;
Frame.origin.y = 0;
yourView.frame = Frame;
[UIView commitAnimations];
Then to move it back:
[UIView beginAnimations:#"myAnimation" context:nil];
CGRect Frame = yourView.frame;
Frame.origin.y = 100;
yourView.frame = Frame;
[UIView commitAnimations];
Changes in frame, alpha and some other parameters will be automatically animated.
You can use animations like so:-
[UIView animateWithDuration:2.0 animations:^{
[scrollview setframe:CGRectMake(xpos, ypos, width, height)];
}];
If you want to slide the scrollview on or off the screen set its y position - the bottom of the view is you want to hide it, the normal y position if you want to show it.
The 2.0 is an animation length, this can be changed to whatever you need it to be!
You can do this by using simple view animations. Here's an example of how you might do this:
// myScrollView is your scroll view
-(void)toggleShow{
CGFloat targetAlpha = myScrollView.alpha == 1 ? 0 : 1;
CGFloat yPosition = targetAlpha == 1 ? 0 : self.view.frame.size.height;
[UIView animateWithDuration:1.0 animations:^{
myScrollView.frame = CGRectMake(myScrollView.frame.origin.x, yPosition, myScrollView.frame.size.width, myScrollView.frame.size.height);
myScrollView.alpha = targetAlpha;
}];
}
targetAlpha will always be the opposite of the current state (1 or 0), and if it's 0 then the y position will be set to the bottom of the parent view. Using the new-school UIView animations API with blocks we can execute these changes to the scroll view over 1 second (in my example).
ScrollView appers from down side of screen with animation. I think this up-animation is what you want.
// ScrollView appearing animation
- (void)ScrollViewUpAnimation
{
// put the scroll view out of screen
CGRect frame = ScrollView.frame;
[self.view addSubview:ScrollView];
ScrollView.frame = CGRectMake(0, 460, frame.size.width, frame.size.height);
// setting for animation
CGPoint fromPt = ScrollView.layer.position;
CGPoint toPt = CGPointMake(fromPt.x, fromPt.y - frame.size.height - 44);
CABasicAnimation* anime =
[CABasicAnimation animationWithKeyPath:#"position"];
anime.duration = 0.2;
anime.fromValue = [NSValue valueWithCGPoint:fromPt];
anime.toValue = [NSValue valueWithCGPoint:toPt];
// change the position of Scroll View when animation start
[ScrollView.layer addAnimation:anime forKey:#"animatePosition"];
ScrollView.layer.position = toPt;
}
I'm doing some custom animations to change views in a single method. I already removed "fromView" from superView using [UIView setAnimationDidStopSelector:#selector(removeFromSuperview)], but I also want to enable user interaction after the end of the animation.
Here's my code:
-(void) switchFrom:(UIViewController*) fromViewController To:(UIViewController*) toViewController usingAnimation:(int) animation{
UIView *fromView = fromViewController.view;
UIView *toView = toViewController.view;
/*************** SET ALL DEFAULT TRANSITION SETTINGS ***************/
// Get the current view frame, width and height
CGRect pageFrame = fromView.frame;
CGFloat pageWidth = pageFrame.size.width;
// Create the animation
[UIView beginAnimations:nil context:nil];
// Create the delegate, so the "fromView" is removed after the transition
[UIView setAnimationDelegate: fromView];
[UIView setAnimationDidStopSelector:#selector(removeFromSuperview)];
// Set the transition duration
[UIView setAnimationDuration: 0.4];
/*************** IT DOESN'T WORK AT ALL ***************/
[toView setUserInteractionEnabled:NO];
[UIView setAnimationDelegate: toView];
[UIView setAnimationDidStopSelector:#selector(setUserInteractionEnabled:)];
[toView setUserInteractionEnabled:YES];
// Add the "toView" as subview of "fromView" superview
[fromView.superview addSubview:toView];
switch (animation) {
case AnimationPushFromRigh:{
// Position the "toView" to the right corner of the page
toView.frame = CGRectOffset(pageFrame, pageWidth,0);
// Animate the "fromView" to the left corner of the page
fromView.frame = CGRectOffset(pageFrame, -pageWidth,0);
// Animate the "toView" to the center of the page
toView.frame = pageFrame;
// Animate the "fromView" alpha
fromView.alpha = 0;
// Set and animate the "toView" alpha
toView.alpha = 0;
toView.alpha = 1;
// Commit the animation
[UIView commitAnimations];
}
.
.
.
Any idea how can I call this two methods in setAnimationDidStopSelector and actually make them work together?
EDIT 1
Tried #safecase code like this, replacing this commented block:
/*************** IT DOESN'T WORK AT ALL ***************
[toView setUserInteractionEnabled:NO];
[UIView setAnimationDelegate: toView];
[UIView setAnimationDidStopSelector:#selector(setUserInteractionEnabled:)];
[toView setUserInteractionEnabled:YES];
*************** IT DOESN'T WORK AT ALL ***************/
// Remove the interaction
[toView setUserInteractionEnabled:NO];
[fromView setUserInteractionEnabled:NO];
// Create the animation
[UIView animateWithDuration:0.4 animations:^{
[fromView performSelector:#selector(removeFromSuperview)];
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.4
animations:^{
C6Log(#"finished");
[toView performSelector: #selector(setUserInteractionEnabled:)];
}];
}];
The "toView" is removed instead of the "fromView" is removed :(
The buttons continue to be interactive during the animation
Do you know beginIgnoringInteractionEvents and endIgnoringInteractionEvents?
Normally, if you don't want any userInteraction during an animation, you would use those.
Anyway you still need correct callbacks to trigger them.
You need to define your own method, e.g. remove: and pass that as the selector. In the method, just use the passed UIView to remove it.
-(void)remove:(id)sender {
UIView *v = (UIView*)sender;
[v removeFromSuperview];
}
You can use this:
[UIView animateWithDuration:0.4
animations:^{ [self performSelector:#selector(removeFromSuperview)]; // other code here}
completion:^(BOOL finished){ [UIView animateWithDuration:0.4
animations:^{ [self performSelector:#selector(setUserInteractionEnabled:)]; //other code here}]; }];
Hope helpful.
I think u can use to enable user interaction
self.view.userInteractionEnabled=NO;
I ended up creating a Category extension to UIView… and it finally works!
UIView+Animated.h code
#import <UIKit/UIKit.h>
#interface UIView (Animated)
- (void) finishedAnimation;
#end
UIView+Animated.m code
#import "UIView+Animated.h"
#implementation UIView (Animated)
- (void) finishedAnimation{
C6Log(#"FinishedAnimation!");
[self removeFromSuperview];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
#end
Then, I #imported this extension in my coordinating controller:
C6CoordinatingController.h partial code
#import "UIView+Animated.h"
And called the selector in setAnimationDidStopSelector:
C6CoordinatingController.m partial code
// Create the delegate, so the "fromView" is removed after the transition
[UIView setAnimationDelegate: fromView];
// Ignore interaction events during the animation
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
// Set the transition duration
[UIView setAnimationDuration: 0.4];
// Call UIView+Animated "finishedAnimation" method when animation stops
[UIView setAnimationDidStopSelector:#selector(finishedAnimation)];
So, I ended up using #jaydee3 and #Mundi concepts and it works like a charm!
Thank you guys!
I'm building a basic calculator app. The calculator is already fully functional with basic features. The problem I'm having is I ran out of room on the screen to add other, more advanced features. Ideally what I would like to do is create some kind of subclass and view that slides up to to the bottom of the label (where the completed calculations are displayed), when a button on the bottom of the screen is pressed. In other words, I want a view with more operators and computation options to slide up to the bottom of the label and I dont want this view to cover up any digits that are being displayed in the label. Is there anyway to achieve this?
Yes, you can. When your button is pressed, create your new view (with the extra functions), add it as a subview to self.view, and animate a change to it's frame, so that it's frame changes from below the visible view to just below your digits.
Like this:
-(void) buttonPressed {
UIView *myNewView = << create your view >>
myNewView.frame = CGRectMake(0,480, 320,200); // or whatever your width and height are
// 480 means it will be below the visible frame.
[self.view addSubview: myNewView];
float bottom_Y_of_digit_display = 100;// or wherever it is...
[UIView beginAnimations:nil contenxt:nil];
[UIView setAnimationDelay: 0.0];
[UIView setAnimationDuration: 1.0]; // one second.
myNewView.frame = CGRectMake(0,bottom_y_of_digit_display, 320,200);
[UIView commitAnimations];
}
You can use UIAnimations to create an animation out of any changes to UIView properties. You can make your UIView hidden by settings its frame.origin.y to 480 and then change the rect and wrap it in a UIAnimation.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
[UIView commitAnimations];
UPDATE
If you are targeting iOS 4.0 and later then you should use the new UIAnimations interface.
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:0.75 delay:0 options:options
animations:^(){
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
}
completion:^(BOOL finished){
//Do something upon completion
}];
I have a view that I want to extend on the left side using an animation. All borders but the left one should remain the same, so the x position and the width of the view are changing.
I use this code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:5.0];
self.frame = CGRectMake(self.frame.origin.x-100,
self.frame.origin.y,
self.frame.size.width+100,
self.frame.size.height);
[UIView commitAnimations];
If I run this code, the width of the view is set to the new value immediately and then the view is moved to the new x point, but why? How can I change this behaviour?
Thanks for your ideas!
Your code runs fine for me. How are you running it? Calling -setFrame is the right choice for what you're doing. Here is what my custom view looks like:
#import "TestView.h"
#implementation TestView
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
- (void)dealloc {
[super dealloc];
}
- (void)go;
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:5.0];
self.frame = CGRectMake(self.frame.origin.x-100,
self.frame.origin.y,
self.frame.size.width+100,
self.frame.size.height);
[UIView commitAnimations];
}
#end
I create an outlet from my view controller of type TestView and connect it and set its type in IB. Then I create a button whose handler calls [customView go]; Seems to work fine.
Okay, I made it woring now. The problem was that my view was a UIButton and I set the title and background with the setBackground:forState: and setTitle:forState:.
It seems that the background of the view is not animatable. I use the work around that I add my own background with a UIImageView.
Thanks for your replies!