Animation is not coming out correctly - ios

I'm creating a menu that slides from the bottom and up via a UIButton that is pressed to activate the animation. But the animation is coming out incorrectly. It is supposed to work like this -https://youtu.be/79ZQDzzOHLk?t=2m52s (but in portrait mode) But here's how it works after I coded it:
And here's the codes for the animation in the viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
draw1 = 0;
scrollView.frame = CGRectMake(0, 300, 480, 55);
[scrollView setContentSize:CGSizeMake(480, 55)];
openMenu.frame = CGRectMake(220, 270, 60, 30);
}
- (IBAction)OpenMenu:(id)sender {
if (draw1 ==0) {
draw1 = 1;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIButton beginAnimations:nil context:nil];
[UIButton setAnimationDuration:0.5];
[UIButton setAnimationDelay:0.0];
[UIButton setAnimationCurve:UIViewAnimationCurveEaseOut];
scrollView.frame = CGRectMake(0, 245, 568, 55);
openMenu.frame = CGRectMake(220, 200, 60, 30);
[self.view bringSubviewToFront:scrollView];
[UIView commitAnimations];
} else {
draw1 = 0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIButton beginAnimations:nil context:nil];
[UIButton setAnimationDuration:0.5];
[UIButton setAnimationDelay:0.0];
[UIButton setAnimationCurve:UIViewAnimationCurveEaseOut];
scrollView.frame = CGRectMake(0, 300, 568, 55);
openMenu.frame = CGRectMake(220, 270, 60, 30);
[self.view bringSubviewToFront:scrollView];
[UIView commitAnimations];
}
}
#end
How do I fix it so the UIButton comes at the bottom of the screen in portrait mode and it goes up and down like in the Youtube tutorial?

Change it to this:
#import "ViewController.h"
#define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
draw1 = 0;
scrollView.frame = CGRectMake(0, SCREEN_HEIGHT-55, SCREEN_WIDTH, 55);
[scrollView setContentSize:CGSizeMake(SCREEN_WIDTH, 55)];
[scrollView setContentSize:CGSizeMake(480, 55)];
}
- (IBAction)OpenMenu:(id)sender {
if (CGAffineTransformIsIdentity(scrollView.transform)) {
[UIView animateWithDuration:0.5 animations:^{
scrollView.transform = CGAffineTransformMakeTranslation(0, 55);
}];
} else {
[UIView animateWithDuration:0.5 animations:^{
scrollView.transform = CGAffineTransformIdentity;
}];
}
}
#end
or, just change this method from what is above to the following (it's the same thing, just more elegant and simpler):
- (IBAction)OpenMenu:(id)sender
to this:
- (IBAction)OpenMenu:(id)sender {
[UIView animateWithDuration:0.5 animations:^{
scrollView.transform = CGAffineTransformIsIdentity(scrollView.transform) ?
CGAffineTransformMakeTranslation(0, 100):CGAffineTransformIdentity;
}];
}

Related

Keep UIButton Size the same when activated multiple times

I have a UIButton constraints set to width and height 80 by 80. But when I press the UIbutton to activate a UIScrollView menu, the constraints changes and the button looks like this the image below. (The button is the blue oval shape at the bottom of the screen)
Here's the viewwcontroller.m codes for the UIbutton and UIscrollview animations.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
draw1 = 0;
scrollView.frame = CGRectMake(0, 300, 480, 55);
[scrollView setContentSize:CGSizeMake(480, 55)];
openMenu.frame = CGRectMake(220, 270, 60, 30);
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
draw1 = 1;
}
- (IBAction)OpenMenu:(id)sender {
if (draw1 ==0) {
draw1 = 1;
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
scrollView.frame = CGRectMake(0, 1000, 568, 200);
openMenu.layer.frame = CGRectMake(self.view.center.x - 30, self.view.frame.size.height - 80, 60, 30);
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
} else {
draw1 = 0;
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
scrollView.frame = CGRectMake(0, 300, 568, 200);
openMenu.layer.frame = CGRectMake(self.view.center.x - 30, 270, 60, 30);
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
}
}
#end
How can you make it so the button constraints says to 80 by 80 and doesn't change when it is activated?
Please check your selected image. I guess its size is over 80-80. Or maybe, its height > width.

Why does iAd banner interferes with my UIView animations

I have an iAd that I created following this tutorial and for some reason when the iAd shows-up any animation going on at that time stops. In other words the animations work fine until the iAd apears and as soon as the iAd apears any animation going at that moment stops or it goes back to its original position without finishing the animation.
This is the code I have for the iAd
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_adBanner = [[ADBannerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, 320, 50)];
_adBanner.delegate = self;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!_bannerIsVisible)
{
if (_adBanner.superview == nil)
{
[self.view addSubview:_adBanner];
}
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, -banner.frame.size.height);
[UIView commitAnimations];
_bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (_bannerIsVisible)
{
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, banner.frame.size.height);
[UIView commitAnimations];
_bannerIsVisible = NO;
}
}
And this is one of the animations I have
- (IBAction)showHideBlackboard:(id)sender
{
[UIView animateWithDuration:0.6 delay: 0.0 options: UIViewAnimationOptionCurveEaseIn animations:^
{
self.controlsView.frame= CGRectMake(10, 10, 250, 250);
}completion:^(BOOL finished)
{
[UIView animateWithDuration:0.6 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
{
self.drawingView.alpha = 1.0;
self.drawingView.frame= CGRectMake(10, 10, 350, 350);
}completion:nil ];
}];
}
Any idea why does the iAd interferes with UIView animations?
I recently had a similar problem. It turned out that avoiding the option
self.translatesAutoresizingMaskIntoConstraints = NO;
in my UIView subclass solved the problem.

Hide and Add UITabbarController

I'm new in ios Development. I have some question.
Now, in my project i have UITabBarController1 with 2 viewControllers(ViewController1, ViewController2).
ViewController1 is start Page.
When I run Every Page(ViewController1, ViewController2, ViewController3, ...) have UITabBarController.
But in some page(Example : ViewController4) i want to hide and add New UITabBarController2
in ViewController4
if I use command "hideButtomBar" in ViewController4 : UITabBarController is not appear.
if I don't use command "hideButtomBar" in ViewController4 : UITabBarController1 and UITabBarController2 is appear(both)
how to fixed it
thank for help and sorry for my mistake about english. ^^
Try using this to hide tabbar
- (void)hideTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
float fHeight = screenRect.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) ){
fHeight = screenRect.size.width;
}
for(UIView *view in tabbarcontroller.view.subviews){
if([view isKindOfClass:[UITabBar class]]){
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}else{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
view.backgroundColor = [UIColor blackColor];
}
}
[UIView commitAnimations];
}
and
[self hideTabBar: UITabBarController1];
app.tabBarController.tabBar.hidden=TRUE;
app.tabBarController.tabBar.hidden=TRUE;
//Set some tab
[app.tabBarController setSelectedIndex:0];

Display animating view within ViewController

EDITED:
I had created a slide in menu for my view and it works as i wanted, this was the original guide that I used.
http://www.youtube.com/watch?v=79ZQDzzOHLk
My goal was to get this programmed once in a class and get it to work on any view controller that i decided to call it in.
Thanks to #harsh.prasad and some additional research I have managed to get this to work to a point where it works as I want apart apart from linking buttons on to it.
So to update this question in the hope it may help someone else.
This is what I did:
I created a UIView class and called it MenuOne.
MenuOne.h
#import <UIKit/UIKit.h>
#interface TFMenuOne : UIView {
// Pop Up Menu
IBOutlet UIScrollView *scrollView;
IBOutlet UIButton *openMenu;
int draw1;
IBOutlet UIButton *backButton;
}
// Pop Up Menu
- (IBAction)openMenu_clicked:(id)sender;
// Reset draw1 to 0
- (void) resetView: (id) sender;
#property (retain, nonatomic) IBOutlet UIScrollView *scrollView;
#end
MenuOne.m
#import "TFMenuOne.h"
#implementation TFMenuOne
#synthesize scrollView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
draw1 = 0;
scrollView = [[UIScrollView alloc] init];
[scrollView setBackgroundColor:[UIColor whiteColor]];
[scrollView setFrame:CGRectMake(0, 315, 568, 5)];
[scrollView setContentSize:CGSizeMake(568, 5)];
backButton = [[UIButton alloc] init];
[backButton setBackgroundColor:[UIColor greenColor]];
backButton.frame = CGRectMake(224, 350, 120, 30);
openMenu = [[UIButton alloc] init];
[openMenu setBackgroundImage:[UIImage imageNamed:#"menu-button-#2.png"]
forState:UIControlStateNormal];
openMenu.adjustsImageWhenHighlighted = NO;
[openMenu addTarget:self
action:#selector(openMenu_clicked:)
forControlEvents:UIControlEventTouchUpInside];
openMenu.frame = CGRectMake(256, 269, 64, 46);
[self addSubview:scrollView];
[self addSubview:backButton];
[self addSubview:openMenu];
}
return self;
}
// Allow for touch even through transparent View class
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *view in self.subviews) {
if (!view.hidden && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
return YES;
}
return NO;
}
- (void) resetView: (id) sender {
draw1 = 1;
[self openMenu_clicked:sender];
}
- (IBAction)openMenu_clicked:(id)sender {
if (draw1 == 0) {
draw1 = 1;
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
scrollView.frame = CGRectMake(0, 260, 568, 60);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
openMenu.frame = CGRectMake(256, 214, 64, 46);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
backButton.frame = CGRectMake(224, 275, 120, 30);
} completion:^(BOOL finished) {
}];
} else {
draw1 = 0;
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
scrollView.frame = CGRectMake(0, 315, 568, 5);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
openMenu.frame = CGRectMake(256, 269, 64, 46);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
backButton.frame = CGRectMake(224, 350, 120, 30);
} completion:^(BOOL finished) {
}];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
After a lot of trial and error, in order to get this UIView class to appear on multiple ViewControllers I call the view like this in the m file of the view controller. The obstacles I ran in to was that the menu would open but when I left the view controller to go to another view controller the menu would be in the state it was in when i left, it wouldn't reset back to closed. The code below covered that thanks again to #harsh.prasad. I also managed to get the menu to animate in.
#interface TFMapViewController ()
{
TFMenuOne *menuView;
}
#end
#implementation TFMapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
[menuView resetView:nil];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
menuView = [[TFMenuOne alloc] initWithFrame:CGRectMake(0, 51, 568, 320)];
[self.view addSubview:menuView];
}
- (void) viewDidAppear:(BOOL)animated
{
[UIView animateWithDuration:0.5 delay:0.5 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
menuView.frame = CGRectMake(0, 0, 568, 320);
} completion:^(BOOL finished) {
}];
}
- (void) viewDidDisappear:(BOOL)animated
{
[menuView resetView:nil];
[UIView animateWithDuration:0.0 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
menuView.frame = CGRectMake(0, 51, 568, 320);
} completion:^(BOOL finished) {
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// Allows for Exit button to work
- (IBAction)returned:(UIStoryboardSegue *)segue {
}
#end
I you want you can use tabsController if that kind of feature you want, otherwise create a class of your slide in menu view and then you can use it in all of your views as you like. No same piece of code is to be rewritten.
EDIT:
Suppose you have created a class CustomMenuView which basically creates your menu view. So now you can use this in every view controller you want to use it in in the following way:
CustomMenuView *menuView = [CustomMenuView alloc] initWithFrame:CGRectMake(0, 200, 320, 100);
menuView.<properties you want to pass> = <set properties here>;
[self.view addSubView:menuView];
This will set the view with the custom menu and then you can handle the actions in this menu.
1)Here is an old tutorial for creating menu - http://www.raywenderlich.com/32054/how-to-create-a-slide-out-navigation-like-facebook-and-path/projectlayout
2)A better way is to create Drawer menu With container views. You can read more about container views from WWDC videos.
3)Or if you are lazy to d it yourself, try this library http://cocoacontrols.com/platforms/ios/controls/jtrevealsidebar
P.S. No , you do not havev to repeat the code.
You can try this,
First make a view on the origin point x = 0 y = 480 (for iphone4) and then run this code.
CGRect theFrame = self.viewMenuShare.frame;
theFrame.origin = CGPointMake(0, 480);
self.viewMenuShare.frame = theFrame;
theFrame.origin = CGPointMake(0,480 - 187);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f];
self.viewMenuShare.frame = theFrame;
[UIView commitAnimations];

Toggle Fullscreen action with Double Tap

Looking for a way to implement a "full-screen" action reversible with double tap but I did not succeed!
More in detail, there are 2 UIView :
- topViewContainer
- bottomViewContainer
When I double-tap on the superview, the view "bottomViewContainer" extends to full-screen, and I re-double tap, the view returns to its original size.
It should work in portrait mode and Landscape Mode!
This is what I've done until now:
-(void)handleDoubleTap:(UITapGestureRecognizer *)sender {
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
if (sender.numberOfTapsRequired == 2){
NSLog(#"if gesture up - LS");
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
topContainerView.frame = CGRectMake(0.0, -160.0, 480.0, 244.0);
bottomContainerView.frame = CGRectMake(0.0, 0.0, 480.0, 300.0);}
completion:^(BOOL finished){
NSLog(#"%f,%f",bottomContainerView.frame.size.width,bottomContainerView.frame.size.height);
}];
} else if (sender.numberOfTapsRequired == 2) {
NSLog(#"else if gesture down - LS");
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
topContainerView.frame = CGRectMake(0.0, -160.0, 480.0, 244.0);
bottomContainerView.frame = CGRectMake(0.0, 84.0, 480.0, 216.0);}
completion:^(BOOL finished){
NSLog(#"%f,%f",bottomContainerView.frame.size.width,bottomContainerView.frame.size.height);
}];
}
}
else if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait) {
if (sender.numberOfTapsRequired == 2) {
NSLog(#"if gesture down - PT");
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
topContainerView.frame = CGRectMake(0.0, 0.0, 320.0, 244.0);
bottomContainerView.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, 640.0);
}
completion:^(BOOL finished){
NSLog(#"%f,%f",bottomContainerView.frame.size.width,bottomContainerView.frame.size.height);
}];
}
else if (sender.numberOfTapsRequired == 2) {
NSLog(#"else if gesture up - PT");
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
topContainerView.frame = CGRectMake(0.0, 0.0, 320.0, 244.0);
bottomContainerView.frame = CGRectMake(0.0, 244.0, self.view.frame.size.width, 216.0);
}
completion:^(BOOL finished){
NSLog(#"%f,%f",bottomContainerView.frame.size.width,bottomContainerView.frame.size.height);
}];
}
}
}
Try this code :
#import "ViewController.h"
#interface ViewController (){
UIView *topContainerView;
UIView *bottomContainerView;
CGRect initialTopContainerView;
CGRect initialBottomContainerView;
BOOL isFullScreen;
}
#end
#implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
CGSize result = [[UIScreen mainScreen] bounds].size;
topContainerView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, result.width, result.height/2)];
topContainerView.backgroundColor = [UIColor redColor];
topContainerView.tag = 1;
[self.view addSubview:topContainerView];
bottomContainerView = [[UIView alloc]initWithFrame:CGRectMake(0.0, result.height/2, result.width, result.height/2)];
bottomContainerView.backgroundColor = [UIColor blueColor];
bottomContainerView.tag = 2;
[self.view addSubview:bottomContainerView];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(handleDoubleTap:)];
tap.numberOfTapsRequired = 2;
[bottomContainerView addGestureRecognizer:tap];
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(handleDoubleTap:)];
tap2.numberOfTapsRequired = 2;
[topContainerView addGestureRecognizer:tap2];
initialTopContainerView = bottomContainerView.frame;
initialBottomContainerView = topContainerView.frame;
isFullScreen = false;
}
return self;
}
-(void)handleDoubleTap:(UITapGestureRecognizer *)sender {
CGSize result = [[UIScreen mainScreen] bounds].size;
int heightSreen = result.height;
int widthSreen = result.width;
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
heightSreen = result.width;
widthSreen = result.height;
}
if (sender.numberOfTapsRequired == 2) {
CGRect newFrameTop;
CGRect newFrameBottom;
isFullScreen = !isFullScreen;
if (isFullScreen) {
if (sender.view.tag == 1) {
newFrameTop = CGRectMake(0, 0, widthSreen, heightSreen);
newFrameBottom = CGRectMake(0, heightSreen, widthSreen, 0);
}else{
newFrameTop = CGRectMake(0, 0, widthSreen, 0);
newFrameBottom = CGRectMake(0, 0, widthSreen, heightSreen);
}
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
topContainerView.frame = newFrameTop;
bottomContainerView.frame = newFrameBottom;
}completion:nil];
}else{
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
topContainerView.frame = CGRectMake(0.0, 0.0, widthSreen, heightSreen/2);
bottomContainerView.frame = CGRectMake(0.0, heightSreen/2, widthSreen, heightSreen/2);
}completion:nil];
}
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Resources