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.
Related
I have code:
ListViewController * listViewController = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self viewWillDisappear:YES];
[listViewController viewWillAppear:YES];
self.view.hidden = YES;
listViewController.view.hidden = NO;
[self viewDidDisappear:YES];
[listViewController viewDidAppear:YES];
[UIView commitAnimations];
But it does not works, and listViewController does not displayed( Please, somebody can tell me the solution of this problem?
Try something like:
UIViewAnimationOptions ops = UIViewAnimationOptionTransitionFlipFromRight;
NSArray *temp = [[NSBundle mainBundle] loadNibNamed:#"NameOfNib" owner:self options:nil];
UIView* newView = [[temp objectAtIndex:0] view];
[UIView transitionFromView:self.view toView:newView duration:1.5 options:ops completion:nil];
self.view = newView; //Lets you control the new view from the current controller (you might want to save a reference to the old one if you need to change back)
As meronix said, non-block based animation is discouraged by Apple for the newer iOS versions. The above method is the "approved" way to do it.
Just so you know, the viewWillAppear, viewDidDisappear, and similar methods aren't methods that YOU call to make the view do things. They're called automatically when these things happen.
Your code had a few misunderstandings; I've commented on them below
//This looks fine (depending on what is in the nib)
ListViewController * listViewController = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
//Normally I use these to move things around, not change the view
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self viewWillDisappear:YES]; //These two methods aren't things that you call
[listViewController viewWillAppear:YES];
self.view.hidden = YES; //If you're flipping or otherwise moving a view out of
listViewController.view.hidden = NO; //sight then you don't need to hide/unhide views
[self viewDidDisappear:YES]; //Same as above, you don't call these
[listViewController viewDidAppear:YES];
[UIView commitAnimations];
Remove unnecessary code and just write this ...
ListViewController * listViewController = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self.view addSubview:listViewController.view];
[UIView commitAnimations];
it cannot work!
you just create and allocate a UIViewController, but never push it on any stacks, or add its view to a visible view.
when you set listViewController.view.hidden to no, you are not magically showing it on screen: you need to add its view to a view (or window) which is already on screen...
ps beginAnimation is deprecated: use blocks animation instead...
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;
}
}
i am working with page curling effect .on click of a button i was able to transit the page(i.e between the UIViews).the following code depicts the same
UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.5];
if ([sender tag] == 1) {
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:placeholder cache:YES];
}
else {
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:placeholder cache:YES];
}
if (view1OnTop) {
[view1 removeFromSuperview];
[placeholder addSubview:view2];
}
else {
[view2 removeFromSuperview];
[placeholder addSubview:view1];
}
[UIView commitAnimations];
view1OnTop = !view1OnTop;
with this i was able to curl between UIViews ,but my question is , will i be able to apply this kind of transition between two or more classes???
thanks in advance
Not everything is animatable. Only parts of UIKit are. So if you mean to ask if any subclass of NSObject can be animated then no they can't. If you mean to ask if whether subclasses of UIView can be animated then the answer would be yes. They can be different subclasses too. While this is possible, it doesn't mean it will give us the right results. They might end up looking pretty weird. You might not want to do that.
Layers are animatable too.
However it all depends on what you mean by classes.
Animating to a new view controller
Say you want to alter the way you shift between view controllers, you can use transitionWithView:duration:.. class method of UIView. An example,
SecondViewController * viewController = [[[SecondViewController alloc] initWithNibName:nil bundle:nil] autorelease];
[UIView transitionWithView:self.view.window
duration:1.0f
options:UIViewAnimationOptionTransitionCurlUp
animations:^{
[self.navigationController pushViewController:viewController animated:NO];
}
completion:NULL];
This will use the curl up transition when pushing the new view controller.
For iOS versions older than 4.0
Since they don't support block based animation APIs, you will have to do this,
[UIView beginAnimations:#"Curl up" context:NULL];
[UIView setAnimationDuration:1.0f];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.window cache:YES];
[self.navigationController pushViewController:viewController animated:NO];
[UIView commitAnimations];
I want to know how to change view on button click in iPhone without navigation controller?
If you're doing this with a UIViewController, you would probably do this like following:
- (IBAction)change {
UIViewController* viewController = [[UIViewController alloc] init];
[self.view addSubView];
// Save the UIViewController somewhere if necessary, otherwise release it
}
Not sure why you don't want to use a UINavigationController though. If it's the navigation bar at the top you don't want to see, there's a property for that so you can hide that bar. Not sure about it's name, probably navigationBarHidden or something like that. You can look that up in the API.
There are many different ways you can do that, and you should possibly provide more information about your app.
A generic way to do it is the following, with animation:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[vc1 viewWillDisappear:YES];
[vc2 viewWillAppear:YES];
vc1.view.hidden = YES;
vc2.view.hidden = NO;
[vc1 viewDidDisappear:YES];
[vc2 viewDidAppear:YES];
[UIView commitAnimations];
In this case, both views are there, you only hide/show them as you need. Alternatively, you could add/remove the view from their superview:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[vc1 viewWillDisappear:YES];
[vc2 viewWillAppear:YES];
[vc1 removeFromSuperview];
[masterController.view addSubview:vc2.view;
[vc1 viewDidDisappear:YES];
[vc2 viewDidAppear:YES];
[UIView commitAnimations];
Place this in Button IBAction method
[mCurrentView removeFromSuperview];
[self.view addSubView:mNewView];
Assume you have two view myView1 and myView2 and one button myUIButton in memory
myView1.tag = 1;
myView2.tag = 2;
myUIButton.tag = 1; //Current visible view is myView1
-(void) ButtonCLicked:(id) sender
{
UIButton* myButton = (UIButton*)sender;
if(sender.tag == 1)
{
[myView1 removeFromSuperview];
[self addSubview:myView2]
myButton.tag = myView2.tag;
}
else
{
[myView2 removeFromSuperview];
[self addSubview:myView1]
myButton.tag = myView1.tag;
}
}
You can place two UIView variables in the header file and hide/show one of them or you can make another layer over the existing view like this:
-(IBAction)changeView {
UIView *view = [[UIView alloc] initWithNibName:#"letMeSeeThis" bundle:nil];
[self.view addSubview:view];
}
I have set up a multiview application with two views. The views can be switched using a button in each view (there are two separate actions). I am using the animation UIViewAnimationTransitionFlipFromRight, and when I go from the first to the second view, the view I am going to appears behind the flipping animation. I would like it just to be white. Any help is appreciated.
alt text http://img35.imageshack.us/img35/9982/picture11wu.png
This is the action switching the views:
- (IBAction)switchViewsOne:(id)sender
{
if (self.uLViewController == nil)
{
ULViewController *uLController =
[[ULViewController alloc]
initWithNibName:#"ULView"
bundle:nil];
self.uLViewController = uLController;
[uLController release];
}
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
UIViewController *comming = nil;
UIViewController *going = nil;
UIViewAnimationTransition transition;
if (uLViewController.view.superview == nil)
{
comming = uLViewController;
going = mainViewController;
transition = UIViewAnimationTransitionFlipFromLeft;
}
[UIView setAnimationTransition: transition forView:self.view
cache:YES];
[comming viewWillAppear:YES];
[going viewWillDisappear:YES];
[going.view removeFromSuperview];
[self.view insertSubview: comming.view atIndex:10];
[going viewDidDisappear:YES];
[comming viewDidAppear:YES];
[UIView commitAnimations];
}
You could try using addSubView which just adds it to the top of the stack.
This kind of bug can be if comming.view is nil
[self.view insertSubview: comming.view atIndex:10];
Check, maybe your nib isn't loaded properly
ULViewController *uLController = [[ULViewController alloc] initWithNibName:#"ULView" bundle:nil];
NSLog(#"Loaded controller %#:", uLController);