UIView animation snaps into place without moving - ios

I'm trying to do a simple animate of a UIView and the problem is that the view doesn't expand/collapse as I want it to do, it only snaps to the end of the animation without moving there. Here is my code:
- (IBAction)policeReportedChanged:(id)sender {
if (self.policeReportedSwitch.isOn) {
[self.policeReportNumberColl setHidden:NO];
[UIView animateWithDuration:1.0f
animations:^
{
[self.policeReportNumberColl setFrame:CGRectMake(0, 130, 320, 65)];
[self.damageView setFrame:CGRectMake(0, 200, 320, 200)];
}
completion:^(BOOL finished)
{
}
];
} else {
[UIView animateWithDuration:1.0f
animations:^
{
[self.policeReportNumberColl setFrame:CGRectMake(0, 0, 0, 0)];
[self.damageView setFrame:CGRectMake(0, 135, 320, 200)];
}
completion:^(BOOL finished)
{
[self.policeReportNumberColl setHidden:YES];
}
];
}
I have set the animation to reveal the UIView policeReportNumberColl when the switch is turned on and collapsed when it isn't. damageView is a UIView below that should move up or down to take the space where the revealed view are or not. Inside policeReportNumberColl are one UILabel and one UITextfield.
I have checked around a lot but can't find anything other than this should work.
EDIT:
I have played around a bit and figured out that it has something to to with which object is sending the action. It DOES work it I connect the animation to a Touch up inside on a UIButton but it does NOT work if I use on Value Changed on my UISwitch like I want to. See code below:
//Does work
- (IBAction) buttonClicked
{
[UIView animateWithDuration:1.0f
animations:^
{
[self.damageView setFrame:CGRectMake(0, 0, 0, 0)];
}
completion:^(BOOL finished)
{
NSLog(#"Klar");
}
];
}
//Does NOT Work
- (IBAction)switchValueChanged {
[UIView animateWithDuration:1.0f
animations:^
{
[self.damageView setFrame:CGRectMake(0, 0, 0, 0)];
}
completion:^(BOOL finished)
{
NSLog(#"Klar");
}
];
}
Does anyone have any idea how to do this on a UISwitch onValueChanged?

Related

Need to move the top red selector along with the bottom list scrolling

I need to move the above shown red selector along with the bottom horizontal scrollview. Currently it is happening after the scrolling is finished.
Here is my code that I am using:
- (void)scrollViewDidEndDecelerating1:(UIScrollView *)scrollView {
if (scrollView.contentOffset.x == 0) {
[UIView animateWithDuration:0.25 animations:^{
self.selectMessageCatagoriesLabel.frame = CGRectMake(0, 41, [CommonUtils getFlexibleWidth:125], 3);
} completion:^(BOOL finished) {
}];
}
else if (scrollView.contentOffset.x == 375) {
[UIView animateWithDuration:0.25 animations:^{
self.selectMessageCatagoriesLabel.frame = CGRectMake([CommonUtils getFlexibleWidth:125], 41, [CommonUtils getFlexibleWidth:125], 3);
} completion:^(BOOL finished) {
}];
}
else{
[UIView animateWithDuration:0.25 animations:^{
self.selectMessageCatagoriesLabel.frame = CGRectMake([CommonUtils getFlexibleWidth:250], 41, [CommonUtils getFlexibleWidth:125], 3);
} completion:^(BOOL finished) {
}];
}
}
Please check the screenshot for the reference
You can use scrollViewDidScroll method from UIScrollViewDelegate, so you can move your code inside this method. You don't need to use animation in this method, because it called very frequently.

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];

How to get multiple animations to play in order infinitely?

I have three UIViews that i want to animate in a certain order (It is supposed to look like a news ticker with three different labels moving from above then display and then move all the way to the outside of the view). Now this whole process is supposed to repeat infinitely.
This is the code i used:
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^
{
[morningPrayerView setFrame:CGRectMake(0, 0, 320, 30)];
[morningPrayerView setAlpha:1.f];
}
completion:^(BOOL finished)
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[morningPrayerView setFrame:CGRectMake(0, 30, 320, 30)];
[morningPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[middayPrayerView setFrame:CGRectMake(0, 0, 320, 30)];
[middayPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[middayPrayerView setFrame:CGRectMake(0, 30, 320, 30)];
[middayPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[eveningPrayerView setFrame:CGRectMake(0, 0, 320, 30)];
[eveningPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[eveningPrayerView setFrame:CGRectMake(0, 30, 320, 30)];
[eveningPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
//this block is called when the animation is over
}];
} }];
} }];
} }];
} }];
}];
The problem is that only the first animation gets the go and none of the other animations start.
IMHO the UIViewAnimationOptionRepeat switch means to repeat the animation indefinitely, therefore your first animation loops forever and never calls the completion handler. Simply wrap the whole animation setup in method, remove the repeat switches and when the last completion handler is executed, call the method again to repeat the whole show? Something like this:
- (void) animateView {
[UIView animateWithDuration:5.0 animations:^{
// …
} completion:^(BOOL finished) {
[self animateView];
}];
}
That’s probably a retain cycle, but as long as you cancel the animation eventually, it should be OK.

UIView animation needs to be called 2 times to work

Im trying to animate a UIView with this code:
[self.view bringSubviewToFront:RegNrView];
[UIView animateWithDuration:.5 animations:^{
RegNrView.frame = CGRectMake(0, 0, 320, 460);
}
completion:^(BOOL finished) {
}];
The RegNrView is a UIView containing a UITextField and has the frame: (320,0,320,460).
This is called from an IBAction. The first call nothing happens, but the second time it works. Why does it do that?

Hide both Navigation Controller and Tab Bar Controller with animation

I'm trying to hide a UITabBarController and UINavigationController simultaneously when a button is touch. I found a very nice code snippet here How to hide uitabbarcontroller but I have problem when trying to hide and animate both UINavigationController and the tabbarcontroller. I also found a lot of examples on the internet when they hide the tabbar using self.tabBarController.tabBar.hidden = YES but that only hides the button items not the black bar at the bottom.
After playing a lot around I can get to make both animate correctly because I think that it's related to the hiding of the Navigation Controller which makes the size of the whole window to change on the fly.
-(IBAction)touchImage:(id)sender {
if (isImageFullScreen) {
isImageFullScreen = NO;
[self.navigationController setNavigationBarHidden:NO animated:YES];
[UIView transitionWithView:self.view
duration:0.5
options:UIViewAnimationOptionCurveLinear
animations:^
{
hotelImageButton.frame = CGRectMake(0,20,320,92);
[self showTabBar:self.tabBarController];
}
completion:^(BOOL finished)
{
}];
} else {
isImageFullScreen = YES;
[self.navigationController setNavigationBarHidden:YES animated:YES];
[UIView transitionWithView:self.view
duration:0.5
options:UIViewAnimationOptionCurveLinear
animations:^
{
hotelImageButton.frame = CGRectMake(0,0,320,480);
[self hideTabBar:self.tabBarController];
}
completion:^(BOOL finished)
{
}];
}
}
The hideTabBar and showTabBar methods are the ones from the other post I linked above.
I also tried some other combinations but I can't make it look good. Any ideas?
Thanks in advance.
I tried that code now and I see that the UITabBar show animation doesn't take place smoothly.
I managed to make it smoother by adjusting the duration period for the tabbar showing animation to be lower.
[UIView setAnimationDuration:0.2];
Hopefully that works.
EDIT:
Please try this code, it resizes the parent view to be bigger in 1 animation transaction in such a way that only the bars are hidden and the content is shown.
- (IBAction)TestButton1:(UIButton *)sender {
if(!isAnimating){
if(isTabBarAndNavBarHidden){
[UIView transitionWithView:self.view
duration:0.5
options:UIViewAnimationOptionTransitionNone
animations:^
{
isAnimating=YES;
CGFloat statusBar_height=[[UIApplication sharedApplication] statusBarFrame].size.height;
CGFloat screen_height=[UIScreen mainScreen].bounds.size.height;
[self.tabBarController.view setFrame:CGRectMake(self.tabBarController.view.frame.origin.x, 0, self.tabBarController.view.frame.size.width, screen_height)];
[self.navigationController.navigationBar setFrame:CGRectMake(self.navigationController.navigationBar.frame.origin.x, statusBar_height, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
}
completion:^(BOOL finished)
{
isTabBarAndNavBarHidden=NO;
isAnimating=NO;
}];
}else{
[UIView transitionWithView:self.view
duration:0.5
options:UIViewAnimationOptionTransitionNone
animations:^
{
isAnimating=YES;
CGFloat statusBar_height=[[UIApplication sharedApplication] statusBarFrame].size.height;
CGFloat screen_height=[UIScreen mainScreen].bounds.size.height;
[self.tabBarController.view setFrame:CGRectMake(self.tabBarController.view.frame.origin.x, statusBar_height-self.navigationController.navigationBar.frame.size.height, self.tabBarController.view.frame.size.width, screen_height+self.navigationController.navigationBar.frame.size.height+self.tabBarController.tabBar.frame.size.height-statusBar_height)];
[self.navigationController.navigationBar setFrame:CGRectMake(self.navigationController.navigationBar.frame.origin.x, 0, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
}
completion:^(BOOL finished)
{
isTabBarAndNavBarHidden=YES;
isAnimating=NO;
}];
}
}
}
This code is for iPhone 4/4S.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (self.lastContentOffset > scrollView.contentOffset.y)
{
NSLog(#"Scrolling up");
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.tabBarController.tabBar setFrame:CGRectMake(0, 430, 320, 50)];
[self.navigationController.navigationBar setFrame:CGRectMake(0, 20, self.navigationController.navigationBar.frame.size.width,self.navigationController.navigationBar.frame.size.height)];
} completion:
^(BOOL finished) {
[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
} completion:^(BOOL finished) {
//
}];
}];
}
else if (self.lastContentOffset < scrollView.contentOffset.y)
{
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.navigationController.navigationBar setFrame:CGRectMake(0, -60, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
[self.tabBarController.tabBar setFrame:CGRectMake(0, 480, 320, 50)];
} completion:
^(BOOL finished) {
[UIView animateWithDuration:.5 delay:2.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
} completion:^(BOOL finished) {
}];
}];
NSLog(#"Scrolling Down");
}
self.lastContentOffset = scrollView.contentOffset.y;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tabBarController.tabBar setFrame:CGRectMake(0, 430, 320, 50)];
[self.navigationController.navigationBar setFrame:CGRectMake(0, 20, self.navigationController.navigationBar.frame.size.width,self.navigationController.navigationBar.frame.size.height)];
// Do any additional setup after loading the view.
}

Resources