I know that it works if I change the view's frame via the changing of a layer's transform (in this case it simply takes a view with all the subviews and works with it as if it is a single image). It is not good enough for me to use it because:
It is too hard to calculate the appropriate position;
I use HMLauncherView which has some logic based on frames not
transforms.
I tried a lot of ways described here but it seems they are all for autolayout because none of them works. Depending on the type of the autoresizing mask some elements jump to their destination position and some of them are not affected at all or affected via strange ways.
How to solve such issue? Are there ways to solve this via an autoresizing mask?
EDITED
Animation code (the same result is for setting of center/bounds):
[UIView animateWithDuration:0.3 animations:^{
lastLauncherIcon.layer.transform = CATransform3DIdentity;
CGRect r = self.bounds;
r.origin.y = MAX(0, MIN(self.scrollView.contentOffset.y, self.scrollView.contentSize.height - self.bounds.size.height));
launcherIcon.frame = r;
} completion:^(BOOL finished) {
...
}];
The code of layoutSubviews seems to be extra because I have already tried to subclass UILabel which always jumps to the animation destination position. The investigation showed that the frame of this label is set when I set the view's frame/bounds only. In other cases label's setCenter, setFrame and setBounds are called when you call them directly.
This question is very similar but the suggested solution doesn't work for my case. I also found out I had broken something so the view with transformation doesn't appear on iOS 7.1 (maybe 7.x) but works on 8.3.
What I'm trying to reach is similar to what is implemented on youTube app on iPad. The search field is expanding in animation from right to left. I'm trying to do so and i'm getting very strange and not smooth animation, Although left to right is working perfect.
|<-------------------------------|Search Field|
It seems that the origin value is changed first and than the width changed , un like the left-right expanding animation that the origin stays the same.
Thanks
You can use animation just put Search field in dynamically in view and put below code.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30];
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame;
CGRect frTblNote = tblNotes.frame;
frGnrVw.size.height = 0.0;
frGnrVw.size.height += 78.0;
generalView.frame = frGnrVw;
[UIView commitAnimations];
In above code general view is my view which has hight 0 and when some action called at that time view height increase and and we will see that view expanding down in that i can not change view's x and y position But in your case first hide your view and when search action calls set hidden NO of your view and in my code i increase height so you can increase your width and also change it's x position means (decrese) i.e you increase width 320 than you decrese it x position to 320 .
just try it it will work.
you can also put it statically in your story board or in nib just set its width =0 and x= 320.
you have to do like below.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30]; // set duration of animation in seconds.
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame; //get frame of view.
frGnrVw.size.width = 0.0;
frGnrVw.size.width += 320.0;//increase width.
frGnrVw.origin.x -=320.0; // decrese position.
generalView.frame = frGnrVw; //set new frame to view.
[UIView commitAnimations]; // this will require.
you just put your view with search field at the position x=320 ,y = as your requirement ,width = 0 and height = as your requirement.
try it it will work.
Also you can hide like same in reverse order.
means increase its x position and decrease its width with above code.
If my answer helps than please vote up my answer.
I have two UIViews (My bad it is a UIView and a UIButton) which I am animating at the same time. I originally had a view and a containerView which would animate just fine and worked like a charm.
Now only one of my UIViews will move/animate in animateWithDuration even though through debugging the frame of the other view says that it is in a position it is not.
CGRect rect = self.toggle.frame;
CGRect tabRect = self.tabButton.frame;
rect.origin.x = rect.origin.x - rect.size.width;
NSLog(#"%f Before",tabRect.origin.x);
tabRect.origin.x = tabRect.origin.x - rect.size.width;
NSLog(#"%f After", tabRect.origin.x);
[UIView animateWithDuration:0.3 animations:^{ // animate the following:
self.toggle.frame = rect; // move to new location
self.tabButton.frame = tabRect;
}];
NSLog(#"%f AfterAnimation", tabButton.frame.origin.x);
The toggle view moves fine, but the tabButton view does not animate or move. The strange thing is that both the "After" and "AfterAnimation" debugging code returns the same value, which suggests the frame has indeed moved. Is there a specific reason that this will not work when toggle is a UIView when it would work as a UIContainerView?
Note that if I remove the line
self.toggle.frame = rect;
tabButton will animate correctly, but if I move toggle, tabButton will not move regardless of whether it is first in the animation block or second.
Edit: I have tried moving them into separate blocks and to change the center point rather than the frame, to no avail. It seems that if the toggle view moves, the tabButton will not move.
Edit 2: The pictorial evidence.{
In the following screenshots tabButton bg is green and toggle bg is red.
Above: Initial position (toggle is off-screen) correct position
Above: The problem in question toggle is correct tabButton is not
Above: When self.toggle.frame = rect is commented out (tabButton correct, toggle not)
}
Edit 3: It's even worse than I feared.{
I have done a few more tests and even if I take the toggle change out of the animation block to make it an instant thing, the tabButton will still not animate. This makes me think the tabButton may just fundamentally dislike the toggle view and/or myself so will not move just to spite me.
}
Edit 4:{
If I change the tabButton animation to tabButton.frame = CGRectMake(10,10,100,100) the View snaps instantly to that location and animates back to its original position in the same time as the animation duration.
}
I better add more bookkeeping/TLDR information in case things aren't clear.
toggle is an instance of ToggleDraw which is a subview of UIView which I created.
tabButton is a UIButton which is part of my IB viewController and a property of the class
Both toggle and tabButton are subviews of self.view
The animations will work individually with no modifications to the logic of the rects but will not work if they are animated at the same time
toggle animation seems to take precedence over tabButton animation regardless of the order
I had a problem with the animation of an UIView created in IB (the animation didn't start from the current position of the view, and ended in the initial position).
All worked fine after sending layoutIfNeeded() to the underlaying view before the animation block:
self.view.layoutIfNeeded()
UIView.animateWithDuration(0.5) { () -> Void in
...
I think it is not a problem about a UIView Animation. Maybe your toggle posiztion is related to your tabButton. For a try, your can set toggle frame to a rect lick (10, 10, 100,100), then check the result.
I've created an example of what you describe and everything seems to work fine. This is what I used:
UIView *toggle = [[UIView alloc] initWithFrame:CGRectMake(320, 64, 100, 100)];
[toggle setBackgroundColor:[UIColor redColor]];
[self.view addSubview:toggle];
UIButton *tabButton = [[UIButton alloc] initWithFrame:CGRectMake(220, 64, 100, 100)];
[tabButton setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:tabButton];
CGRect rect = toggle.frame;
CGRect tabRect = tabButton.frame;
rect.origin.x = rect.origin.x - rect.size.width;
NSLog(#"%f Before",tabRect.origin.x);
tabRect.origin.x = tabRect.origin.x - rect.size.width;
NSLog(#"%f After", tabRect.origin.x);
[UIView animateWithDuration:1 animations:^{ // animate the following:
toggle.frame = rect; // move to new location
tabButton.frame = tabRect;
}];
What I can suggest is to make sure that the code is being ran on mainthread:
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
self.toggle.frame = rect; // move to new location
self.tabButton.frame = tabRect;
}];
});
Also take into account that the log you have after the animation code is incorrect as it won't run after the animation, but rather right next to asking for the animation.
If you want code to run after the animation you should use:
[UIView animateWithDuration:0.3 animations:^{
self.toggle.frame = rect; // move to new location
self.tabButton.frame = tabRect;
} completion:^(BOOL finished){
NSLog(#"Finished animating!");
}];
I have found a solution to the problem. If I initialise the UIButton (tabButton) programmatically rather than through the interface builder, both views will animate simultaneously.
This however seems very hacky to me, kind of like putting a bandaid over a missing foot and hoping it will sort itself out.
I could not work out the root cause of the problem but at least I could avoid the symptoms.
If anyone knows why the views would not animate when the button was made in the interface builder post an answer here, I am interested in knowing the reason behind this.
Thanks for your help everyone.
I wasn't quiet sure how to word this, but here goes.
I have a couple of UIControls that I am sliding into the view with in the viewWillAppear method. The UIControls animate correctly as well as my graphics inside those UIControls, but the UITextField is not. It should be starting to the right 50 points with an alpha of 0 fading into 1. Instead the UITextFields does this odd masking and from the other direction (left to right instead of right to left, as well as a bit higher on the y axis). Does this have something to do with the UITextField not being ready for display when I start my animation? Below is the code.
nameOfBillViewConstraint.constant = 50;
nameOfBillView.alpha = 0.0;
[UIView animateWithDuration:10
delay: 0.5
options: UIViewAnimationOptionCurveEaseIn
animations:^{
nameOfBillViewConstraint.constant = 10;
nameOfBillView.alpha = 1.0;
[self.view layoutIfNeeded];
}
completion:nil];
Thanks for your help on this.It's more of a visual problem, but I wasn't sure how to display that here...
I'm trying to move and resize a label, but what happens is the label resizes immediately then moves into position. I first tried simply the commented out lbl.frame line. Next I found this question:
How to animate while resizing UIView
And added all the other code except for the contentMode. This did what I wanted, but the Label's font did not adjust downwards as the label shrunk. ( I tick adjust to fit in xib ). Finally adding the contentMode line gave me the same result as my original frame line - shrink immediately first them animate the move.
lbl.contentMode = UIViewContentModeRedraw;
[UIView animateWithDuration:1.0 delay:0.0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^{
//lbl.frame = CGRectMake(x, mStartingLine.frame.origin.y+mStartingLine.frame.size.height, 100, 100);
CGRect theBounds = lbl.bounds;
CGPoint theCenter = lbl.center;
theBounds.size.height = 100;
theBounds.size.width = 100;
theCenter.y = mStartingLine.frame.origin.y+mStartingLine.frame.size.height+50;
theCenter.x = x;
lbl.bounds = theBounds;
lbl.center = theCenter;
}
completion:nil
];
I suspect that the auto text resizing feature doesn't work with Core Animation.
What I would suggest doing is to set the label to it's final size (using it's bounds) then apply a transform to it that shrinks it back down to it's starting size. The end effect of those things is that it should stay at the same apparent size.
Finally, use animateWithDuration:animations: to set the view's transform back to the identity transform, so it grows to it's new size.
I don't know what drawing artifacts this will cause - you'll have to try it.