I am trying to create a sliding menu (like the one in google maps app) in which menu screen should be shown or added as subview over the existing screen on tapping a button. While showing it, the sub view should be animated from left to right. I tried to animate while adding it as subview, but failed in doing so. Can any one suggest how to do it? (or) Can I do it using navigation controller?
Thanks in advance!!
You need to add the subview, and set it's frame out of the screen.(320,0,100,568 for example).
Of course it's better to use auto layout for that.
Add as subview:
[self.view addSubView:sideMenu];
When you want to show it, just change it's frame using animation block.
[UIView animateWithDuration:0.2 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
sideMenu.frame = CGRectMake(220,0,100,568);
} completion:^(BOOL finished) {
}];
As I said, it's better to use auto layout and not setting frames. I did it only for the example.
Related
I have a UIView "MainView" that initially appears as follows:
The gradient bar is part of MainView, the whitespace beneath is part of a Container View subview.
When the search button in top-right is tapped, I animate a searchBar from offscreen to be visible in the view:
I manage to do this by the following code:
CGRect currentViewFrame = self.view.bounds;
currentViewFrame.origin.y += searchViewHeight;
[UIView animateWithDuration:0.4
delay:0.0
usingSpringWithDamping:1.0
initialSpringVelocity:4.0
options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.frame = currentViewFrame;
}
completion:^(BOOL finished)
{
}];
Visually, the result of this animation is perfect. The entire view shifts, and the searchBar is now on screen. However, the searchBar does not respond to interaction. Correct me if I'm wrong, but I expect this is because the MainView's frame no longer includes the screen area that the searchBar now occupies, so its effectively a gesture deadzone.
So this makes me think that instead of lazily animating the entire MainView down to accomodate the searchBar, I must instead individually translate all subviews of MainView one at a time. In this simple situation, that would not be a big problem, but I can envision a circumstance with tens of subviews making that completely unrealistic.
What is the best method to accomplish what I am trying to do? Is there a secret to animating entire views/subviews without having gesture deadzones? Thanks in advance!!
I want to make a UIView animate when it's being closed. I tried reading the following:
http://felipe.sabino.me/ios/2012/05/10/ios-uiview-transition-effects/
iPhone UIView Animation Best Practice
iOS UIView Animation CATransform3DMakeRotation confusion
However, I'd like to make it transition from the side of the screen, as per the image in the Google Chrome app.
Is there another animation that is set for this? I was not able to find it... I'm assuming it has to do with animateWithDuration or a CATransform...can somebody point me in the right direction for this?
[EDIT]
I used the below post for an answer as well as this post:
Setting a rotation transformation to a UIView or its layer doesn't seem to work?
I was able to add multiple animations as per below:
[UIView animateWithDuration: .2
delay: 0
options: (UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
animations:^{self.view.center = CGPointMake(self.view.frame.origin.x * 3, self.view.frame.origin.y * 2), self.view.transform = CGAffineTransformMakeRotation(M_PI_4/2);}
completion:nil];
Previously I was not aware you can add multiple animations so easily. That adds rotation as well as the linear movement together.
Animate your view so it moves offscreen/shrinks/expands/fades, then do the actual removal when the animation ends.
You can do this by altering the properties of the view (position/size/offset) between a beginAnimations/commitAnimations block. UIKit will then animate these properties over the time specified.
E.g something like;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.30f];
view.transform =
CGAffineTransformMakeTranslation(
view.frame.origin.x,
480.0f + (view.frame.size.height/2) // move the whole view offscreen
);
background.alpha = 0; // also fade to transparent
[UIView commitAnimations];
In the animation end notification you can then remove the view.
I've never run Chrome on iOS, so I have to try to guess what your screenshot is showing.
Does the animation go off the screen while shrinking and turning to one side?
And do you mean you want to animate a UIViewController, or a UIView? Are you closing a view controller?
If it's a view controller, how are you managing your view controllers? Are you using a navigation controller, or are you presenting a set of modal view controllers, or some other method?
I am using the code snippet from Tito to add a custom button to my tab bar:
https://github.com/tciuro/CustomTabBar
(Subclassing UITabbarController and adding a custom button using
// .. created a UIButton *button
[self.view addSubview:button];
)
This works great with my storyboard-based app except for the case of a subview within a navigation controller with the option "Hides bottom bar on push" enabled.
This hides the tab bar as promised, but not the custom button.
Seems like the button should be added as a subview to the tab bar itself?
I tried this ugly code which did not even make the button show up:
for(UIView *view in self.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view addSubview:button];
break;
}
}
Any ideas?
UPDATE:
My solution:
In my ApplicationDelegate i define the following methods, which i call whenever needed in the viewWillAppear or viewWillDisappear methods:
-(void)hideCenterButton:(BOOL)animated
{
if(animated){
[UIView animateWithDuration:0.3
delay:0.0f
options:UIViewAnimationCurveLinear
animations:^{
CGRect frame = self.centerButton.frame;
frame.origin.x = -100;
self.centerButton.frame = frame;
}
completion:^(BOOL finished){
}];
}
}
-(void)showCenterButton:(BOOL)animated
{
if(animated){
[UIView animateWithDuration:0.35
delay:0.0f
options:UIViewAnimationCurveLinear
animations:^{
CGRect frame = self.centerButton.frame;
frame.origin.x = (self.view.superview.frame.size.width / 2) - (self.centerButton.frame.size.width / 2);
self.centerButton.frame = frame;
}
completion:^(BOOL finished){
}];
}
}
I had to set the animation's duration to 0.35s to get a smooth effect in harmony with the tab bar.
Why don't you make button your tabbar's part.
tabBarController.tabBar.addSubView(yourButton)
everything would be solve. cheers!
One easy way to handle this would be to create an instance of the button in .h of your file.
UIButton *customTabButton;
When calling the hides bottom bar on push set the button property to hidden and reset it again in the other views if the bottom bar is visible.
shareFbButton.hidden=YES;
You can check this is the viewDidLoad of all the files and put this line of code if needed to make sure you are displaying the button and hiding the button on all the pages you need.
if(self.tabBarController.tabBar.isHidden){
// set or reset the custom button visibility here
}
This is one way.
I think there are 2 ways you can got with this.
1) try to get the button into a view that is above the old top view controller and the tab bar BUT below the new top view controller that is pushed.
2) animate away the button when the new view controller is pushed.
The first will require mucking with the iOS proprietary view hierarchy which is undocumented, unsupported and could change anytime.
The second will be a matter of making the animation appear smooth enough for your user not to notice. It's not entirely a matter of behaving perfect, just appearing appropriately.
I would personally recommend an animation of the the button disappearing (animate it's alpha to 0) and reappearing based on if your view controller that goes over the tab bar is appearing or disappearing.
The animation for a navigation is (I believe) 0.3 seconds. If the button is in the middle of the tab bar, you'll likely want it invisible as the animating in view controller reaches it (if not sooner) so something between 0.1 and 0.15 seconds could be used to animate it out.
Now this does not make the button behave exactly the same as the tab bar, but with the quickness of the transition being so short, it will be unnoticeable really to the user.
Now just to provide a question for you to ask yourself. Why do you need to push a view controller that overlaps the tab bar? Why is that more desirable/necessary than presenting a modal view controller? If you can strongly argue for it, keep at it and good luck, if it's not necessary however, you may be able to achieve the experience you want with a modal view controller.
Check this one to put a button on the UITabBar. See if it works after with hidesBottoBarWhenPushed.
I am trying to animate between 2 subviews. At the moment I've tried different options, each with their own side effects.
The application is a small game with a skills subview, an inventory subview, and a status subview. I want to animate between the skills and the inventory views while leaving the status subview on the bottom of the main view. Below I've listed my various attempts and the side effects from them.
Animate from `animateWithDuration
[UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationCurveEaseIn animations:^{
skillView.hidden = NO;
inventoryView.hidden = YES;
}completion:NULL];
No transitions seems to take place. The views just pop in.
Animate from transitionFromView
[UIView transitionFromView:inventoryView toView:skillView duration:0.5 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished){
inventoryView.hidden = YES;
}];
The transition is done perfectly, but the status view transitions with the other views. Almost as if the main view is animating with everything.
The views are loaded into the main view just hidden in the background and they used to just pop into the main window. However, I would like to animate between the views to have a better application flow. I've seen people remove and add to the main view, but I'm hoping that setting the subviews to be visible/invisible should have the same effect.
Any advice is greatly appreciated.
Core Animation doesn't know how to animate those views apart from their direct ancestor (parent).
Break them into a single container view.
Eg:
Instad of this:
Parent
- Other View
- View A
- View B
- Other View
Have this:
Parent
- Other View
- Container
- View A
- View B
- Other View
See comments to question for more detail.
There is a vertical cover transition. I have been looking around the web for how to do a horizontal cover with no success. Any suggestions?
There's no horizontal cover transition provided in iOS. You'll have to create your own UIStoryboardSegue subclass and implement your own transition animation.
One way to animate the kind of transition I think you're looking for is something like this (warning: untested code):
// add newView to window
[oldView.window insertSubview:newView aboveSubview:oldView];
// assuming newView and oldView both sized to fill screen,
// position newView just to the right of oldView
newView.center = oldView.center + oldView.frame.size.width;
// slide newView over oldView, then remove oldView
[UIView animateWithDuration:0.3
animations:^{ newView.center = oldView.center; }
completion:^(BOOL finished){ [oldView removeFromSuperview]; }];
When you use a navigation controller and then push and pop views from it the effect is a horizontal cover.
As answered by T.J. above, use a navigation controller and it will default to horizontal cover automatically.