Pre-cache UIView's animation? - iphone

I've set up a UIViewController that holds two other controllers:
MainVC -> SubVC1
-> SubVC2
At start, I show the SubVC1's view. The user can then switch to SubVC2's view:
- (void)showOtherSide:(id)sender
{
UIView *currentView = [self.view.subviews objectAtIndex:0];
BOOL flipToRight;
UIView *newView;
if (currentView == subVC1.view)
{
newView = subVC2.view;
flipToRight = YES;
}
else
{
newView = subVC1.view;
flipToRight = NO;
}
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
if (flipToRight)
{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:currentView cache:YES];
}
else
{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:currentView cache:YES];
}
[currentView removeFromSuperview];
[self.view addSubview:newView];
[UIView commitAnimations];
}
The problem now is that even in the simulator the first back and forth flips don't show up, instead the user sees the new view immediately. Because I set the animation caching to YES, the following flips show the animation (at least most of the time!).
I tried to put the animation code in the viewDidAppear: method too, but without any improvement.
Are there any good practices to pre-cache the animations?

Related

UIButton actions

I have a UIButton set up in a storyboard that when pressed animates a UIVIew. I would like the same button to animate/move the UIView back to it's original point when it is pressed a second time.
What is the best way to do this?
thanks for any help or pointers.
this is the code I'm using to animate and move the UIVIew:
I'm using a BOOL named buttonCurrentStatus.
-(IBAction)sortDeals:(UIButton*)sender {
if (buttonCurrentStatus == NO)
{
buttonCurrentStatus = YES;
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = yes");
} else {
buttonCurrentStatus = NO;
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = no");
}
Another more general way is to use an IBAction that will execute one of two methods. Like previous answers, you can use a BOOl value, or int in order to determine what action to use. This is a more general answer, and can be used for many purposes.
First, you will need a BOOL variable. For this example I put the Bool variable as boolVarible (Yes, I know I spelled it wrong). By default I have it set to YES.
bool boolVarible = YES;
I made that a class variable.
-(IBAction)buttonAction:(id)sender {
if (boolVarible == YES)
{
//Execute first action
[self firstAction];
}
else
{
//Execute second action
[self secondAction];
}
}
-(void)firstAction {
//Do something here...
}
-(void)secondAction {
//Do something here...
}
Hopefully, you get the idea. You can then swap actions whenever you want. Just simply change the BOOl value, and then when the button is pressed, it will execute another method. I find this cleaner than doing it all in one action. Good luck.
-(IBAction)sortDeals:(UIButton*)sender {
sender.selected = !sender.selected;
int moveby = (sender.selected) ? 30: -30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
menuTop.frame = CGRectMake(menuTop.frame.origin.x, menuTop.frame.origin.y + moveby, menuTop.frame.size.width, menuTop.frame.size.height);
[UIView commitAnimations];
}
Very Simply Solution for your Question is if you Declare two Boolean Variables in Class where you need to implement this method.your Code will be look like this
In .m file
BOOL Action1;
BOOL Action2;
Now In ViewDidload method
(void)viewDidLoad
{
Action1=TRUE;
Action2=FALSE;
[super viewDidLoad];
}
And now your Method
(IBAction)sortDeals:(UIButton*)sender {
if (Action1 == TRUE)
{
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = yes");
Action1=FALSE;
Action2=TRUE;
}
else
if (Action2 == TRUE)
{
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = no");
Action1=TRUE;
Action2=FALSE;
}
Hope it Works for you.Thanks

how to make the viewcontroller rotate when added through appdelegate window

I have added a viewcontroller in the window of appdelegate class like this:
-(void)showSearchView:(BOOL)view
{
if(view)
{
searchViewController = [[SearchView alloc] initWithNibName:#"SearchView" bundle:nil];
CGRect viewFrame=searchViewController.view.frame;
viewFrame.origin.y=-1024;
viewFrame.origin.x=248;
[window addSubview:searchViewController.view];
searchViewController.view.frame = viewFrame;
[UIView beginAnimations:#"UIBase Hidden" context:nil];
[UIView setAnimationDuration:0.5];
searchViewController.view.transform = CGAffineTransformMakeTranslation(0,1024);
[UIView commitAnimations];
}
else
{
[UIView beginAnimations:#"UIBase Shown" context:nil];
[UIView setAnimationDuration:0.5];
searchViewController.view.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
[self performSelector:#selector(doTHis) withObject:nil afterDelay:1];
}
}
This gets called from other classes through this command
[apd showSearchView:YES];
where apd is object of appdelegate class
Everything is working fine till here but when i try to rotate it does not rotate. I have even returnd YES in the following method and still it does not rotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
What should be done?
Please remember that UIWindow does not rotate. Perhaps You should add a base view controller and do your rotation.

Beginner: Multiview app doesn't switch views correctly

I wrote a basic two-view application that switches from one view to another every time I press a button.
But for some reason when I run it on simulator, both views are always few pixels above the MainWindow.xib view, always being on top of it. And what's strange is that there is no animation when I switch between Views.
What is the problem???
This is what I have in my AppDelegate.m
-(void)switchView:(UIView *)view1 toView:(UIView *)view2{
[UIView beginAnimations:#"Animation" context:nil];
[UIView setAnimationDuration:1.75];
[UIView setAnimationTransition:UIViewAnimationOptionTransitionFlipFromLeft forView:self.window cache:YES];
[view1 removeFromSuperview];
[window addSubview:view2];
[UIView commitAnimations];
}
Here are two very nice examples:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/13427-uiview-slide-transition.html
http://www.dizzey.com/development/ios/simple-uiview-transitions-animation-using-blocks-in-ios-4/
Or this one:
iOS 4.2: Flip image using block animations
Hi Try This,
-(void)switchView:(UIView *)view1 toView:(UIView *)view2
{
view2.frame = self.window.bounds;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view2 cache:NO];
[view1 removeFromSuperview];
[window addSubview:view2];
[UIView commitAnimations];
}
Also try this
[UIView transitionWithView:view2 duration:0.5
options:UIViewAnimationTransitionFlipFromLeft //change to whatever animation you like
animations:^ { [window addSubview:view2]; }
completion:nil];
Can you post some code regarding this .Because if you click on Segment change
it will change the Views.IF you take two views on same interface Builder.
Try out this
IBOutlet UIView *viewA;
IBOutlet UIView *viewB;
in .m file
-(IBAction)SegmentChange
{
if(segment.selectedSegmentIndex==0)
{
viewA.hidden=NO;
viewB.hidden=YES;
}
else if(segment.selectedSegmentIndex==1)
{
[self.View addSubview:viewB];
viewA.hidden=YES;
viewB.hidden=NO;
}
}

How can I present a UIView from the bottom of the screen like a UIActionSheet?

I'd like a UIView to slide up from the bottom of the screen (and stay mid-screen) like a UIActionSheet. How can I accomplish this?
UPDATE:
I am using the following code:
TestView* test = [[TestView alloc] initWithNibName:#"TestView" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
test.view.center = CGPointMake(160,100);
//test.view.frame = CGRectMake(0, 0, 160, 210);
[[[UIApplication sharedApplication] keyWindow] addSubview:test.view];
[UIView commitAnimations];
The view seems to be animating from the corner and appearing in the corner. How can I make it slide up from the bottom? Getting close!
Do what Matt did here, but just change the values and direction. I have code at home to do this from the bottom if you need it later (I'll update this post).
Link: http://cocoawithlove.com/2009/05/intercepting-status-bar-touches-on.html
Also, don't forget to take out the bit of code that shifts the main view downward (so instead the UIView just pops over top like an ActionSheet)
Updated with code:
This is what I use in one of my apps to show/hide a little "options" view:
- (void)toggleOptions:(BOOL)ViewHidden
{
// this method opens/closes the player options view (which sets repeat interval, repeat & delay on/off)
if (ViewHidden == NO)
{
// delay and move view out of superview
CGRect optionsFrame = optionsController.view.frame;
[UIView beginAnimations:nil context:nil];
optionsFrame.origin.y += optionsFrame.size.height;
optionsController.view.frame = optionsFrame;
[UIView commitAnimations];
[optionsController.view
performSelector:#selector(removeFromSuperview)
withObject:nil
afterDelay:0.5];
[optionsController
performSelector:#selector(release)
withObject:nil
afterDelay:0.5];
optionsController = nil;
}
else
{
optionsController = [[PlayOptionsViewController alloc] init];
//
// Position the options at bottom of screen
//
CGRect optionsFrame = optionsController.view.frame;
optionsFrame.origin.x = 0;
optionsFrame.size.width = 320;
optionsFrame.origin.y = 423;
//
// For the animation, move the view up by its own height.
//
optionsFrame.origin.y += optionsFrame.size.height;
optionsController.view.frame = optionsFrame;
[window addSubview:optionsController.view];
[UIView beginAnimations:nil context:nil];
optionsFrame.origin.y -= optionsFrame.size.height;
optionsController.view.frame = optionsFrame;
[UIView commitAnimations];
}
}
One way would be to use the present modal view controller on the view controller:
presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
For more info take a look at the UIViewController documentation.
EDIT: If you want a mid-screen view you'll need to animate it into position as #jtbandes has pointed out. I suggest also adding some candy to UIView animation block:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
myView.center = CGPointMake(x,y);
[UIView commitAnimations];
You can then move it again if you need to go full screen or dismiss it.
You'll have to move the view yourself, by setting its center or frame. I'll let you figure out what to set those to. But for the animation:
// set the view to its initial position here...
[UIView beginAnimations:nil context:NULL];
// move the view into place here...
[UIView commitAnimations];
Check out this post: http://blog.yetanotherjosh.com/post/33685102199/3-ways-to-do-a-vertical-transition-with
I'm going with the modal window approach.
Try this solution.... it works
#pragma mark - Date Selector View PresentModelView with Transparent ViewController
- (void) showModal:(UIView*) modalView {
CGRect rect=modalView.frame;
rect.origin=CGPointMake(0, 0);
self.tutorialView.frame=rect;
UIWindow *mainWindow = [(AppDelegate *)[UIApplication sharedApplication].delegate window];
CGPoint middleCenter;
middleCenter = CGPointMake(modalView.center.x, modalView.center.y);
CGSize offSize = [UIScreen mainScreen].bounds.size;
CGPoint offScreenCenter = CGPointMake(offSize.width / 2.0, offSize.height * 1.5);
modalView.center = offScreenCenter;
if ([[mainWindow subviews] containsObject:modalView]) {
[modalView removeFromSuperview];
}
[mainWindow addSubview:modalView];
[mainWindow bringSubviewToFront:modalView];
// Show it with a transition effect
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
// animation duration in seconds
modalView.center = middleCenter;
[UIView commitAnimations];
}
// Use this to slide the semi-modal view back down.
- (void) hideModal:(UIView*) modalView {
CGSize offSize = [UIScreen mainScreen].bounds.size;
CGPoint offScreenCenter = CGPointMake(offSize.width / 2.0, offSize.height * 1.5);
[UIView beginAnimations:nil context:(__bridge void *)(modalView)];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(hideModalEnded:finished:context:)];
modalView.center = offScreenCenter;
[UIView commitAnimations];
}
- (void) hideModalEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
UIView *modalView = (__bridge UIView *)context;
[modalView removeFromSuperview];
}

Problem Flipping a View

I'm having some trouble getting a view to flip. I have the following code in my View Controller:
- (void)loadFlipsideViewController {
ProblemViewFlipController *viewController = [[ProblemViewFlipController alloc] initWithNibName:#"ProblemViewFlip" bundle:nil];
self.problemViewFlipController = viewController;
[viewController release];
}
- (void) flipView {
if (problemViewFlipController == nil) {
[self loadFlipsideViewController];
}
UIView *mainView = self.view;
UIView *flipView = problemViewFlipController.view;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:([mainView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) forView:self.view cache:YES];
if ([flipView superview])
{
[flipView removeFromSuperview];
[self.view addSubview:mainView];
}
else
{
[mainView removeFromSuperview];
[self.view addSubview:flipView];
}
[UIView commitAnimations];
}
The problem is, is that when I call flipView, the view is replaced with a blank view (i.e. nothing in the view I'm flipping to is displayed).
Is there something obvious I'm missing here? (I suspect there is!)
Not positive, but I think you need to use a 'controller' to flip the views. Looks like you're using one of the flipped views as the controller. Just add a root controller to flip your views.
Code like this should work from the root controller:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES]; // self.view is the root controller's view
[mainViewController viewWillAppear:YES];
[flipViewController viewWillDisappear:YES];
[flipViewController.view removeFromSuperview];
[self.view addSubview:mainViewController.view];
[flipViewController viewDidDisappear:YES];
[mainViewController viewDidAppear:YES];
[UIView commitAnimations];
Based on the variable names, it looks like this is adapted from the default "Utility" application template you get from XCode. If the template project works, and yours doesn't, then you've obviously changed something you shouldn't have :-)
Chances are, one of the outlets in your controller that should be pointing at a view, isn't. Double-check your Nibs, and check the values of the outlets in the debugger. If all else fails, start over again from the template, and see at what point it stops working.