Load a XIB with custom Transition? - iphone

Is it possible (at all) to load a XIB with custom AnimationTransition?
What I have done, is creating an animation that "Covers" the screen, and what I want is that after that animation has done playing, I would like it to display the new XIB.
I cant seem to find any proper solution to this...Any ideas?
To be more clear: Press a button --> Play Animation (cover screen) --> Load XIB.
Hello again! Yes, the last way you described is the way I am doing it. I have two UIViews (Might be wrong already there), that are placed off-bounds on each side, (like x.-160.y.0 and x.320y.0)
-(IBAction) leftDoor{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
closeDoor1.center = CGPointMake( closeDoor1.center.x +160, closeDoor1.center.y);
[UIView commitAnimations];
}
-(IBAction) rightDoor{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
closeDoor2.center = CGPointMake( closeDoor2.center.x -160, closeDoor2.center.y);
[UIView commitAnimations];
}
So, what I am going to do is not to "split" the current view and then open a new XIB, the effect I am searching for is a "closing door" effect, thats why I used UIView ( thought I place graphics on top of those, like two ImageViews). Then, for loading the new XIB...This is where im really puzzled. My first way of trying this out was to make three IBActions, including the two I mentioned above, and then apply all three (multiple actions) to a button. So for switching views I did something like this: `-(IBAction) newViewDisplay:(id)sender{
theView *newViewController = [[theView alloc]
initWithNibName:#"theView" bundle:nil];
[self.view addSubview:newViewController.view];
}
`
As you said, this might be over my head, but if I just got some directions, I´ll walk miles to make this work. It would really give my app a facelift. A huge thanks for taking time to answer my question, All the best/Andy

What are you covering the screen with?
Think of it this way, (it sounds like) you have 2 views, the old one and the new one that is stored in this xib. The animation is secondary.
You need to load the new view, then display it (can be off-screen), then animate it (move it) into the place you want it to go. If you want to split it into two parts, one at the bottom and one at the top of the screen, then meet in the middle, I think that's both complicated and above you skill level. (Not trying to be mean here).
If you are trying to do a split animation as described, it can be done, but you need to 'fake it'. It would involve taking a 'screenshot' (of sorts), splitting it, moving these two images so they meet with an animation, loading the view underneath, and then removing the images. Tricky stuff.
Do you have to have this sort of animation?
If you could post the code you have, I can rearrange it, and add to it, for you.
You'll need to clarify what it is exactly you want to do, though.
UPDATE 3: I added another option for autoreverse.
//You can add both doors into one animation block.
//Create an animation block. Ease Out is better for this animation but you can change it.
[UIView animateWithDuration:1.0 delay:0.0 options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAutoreverse) animations:^{
closeDoor1.center = CGPointMake( closeDoor1.center.x +160, closeDoor1.center.y);
closeDoor2.center = CGPointMake( closeDoor2.center.x -160, closeDoor2.center.y);
}completion:^(BOOL finished){
if (finished) {
//When finished, create the VC if it doesn't exist, and insert it below the 'closed door'.
if (newViewController == nil) {
UIViewController *newViewController = [[UIViewController alloc] initWithNibName:#"theView" bundle:nil];
}
[self.view insertSubview:newViewController.view belowSubview: closeDoor2];;
[self.closeDoor1 removeFromSuperview];
[self.closeDoor2 removeFromSuperview];
}
}];

Related

Touch issue during UIView Animation

I am animating UIView when user touches on custom dropdown to show picker View from bottom side.UIView contains Pickerview...so when I change it's frame to move upwards.I get what I want, but pickerView doesn't recognize touch !(see screenshot below)
code is like this
CGRect pickerFrame=self.pickerSheet.frame;
CGRect viewFrame=self.view.frame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:SHEET_ANIMATION_DURATION];
//change Frame of View containing UIPickerView
pickerFrame.origin.y=202+animatedDistance;
viewFrame.origin.y-=animatedDistance;//animated distance is value by which view needs to move upward.
[self.pickerSheet setFrame:pickerFrame];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
screenshot
first of all, ++please**, stop using this animation declaration, and bedin use new, block animation:
[UIView animateWithDuration:SHEET_ANIMATION_DURATION
delay:0
options:nil
animations:^{
pickerFrame.origin.y=202+animatedDistance;
viewFrame.origin.y-=animatedDistance;
}
completion:^(BOO f){
//any actions after animation ended
}];
Second, I think your problem is somewhere else. May by, you implementing your touches or picker wrong.
Please start using the new , better animation block , but I think there is something missing in your code , you need to put the code below :
UIViewAnimationOptionAllowUserInteraction
Put this code in options in the new animation block , or find a way to put it in the old animation block

removeFromSuperview with animation and views management

I did some digging around about this, but nothing really seems to answer my particular question (not even this: Is it possbile to removeFromSuperview with Animation?).
Basically, my app starts with a welcome screen, where a user clicks on "sign in", then goes to the sign in view, then getting to a tab bar view, which is the actual app.
The way I did it, is that I wrote a custom class - TabBarController, which sets up all the tabs and their respective view controllers. Now, when the user clicks on "sign in" i am calling removeFromSuperview and present the tabbar.
I am trying to find a way to animate the transition from the sign in page to the tab bar. I tried some proposed solutions around here, but none seems to do the job. Here is my code in the signin.m view controller. I am looking to animate out the current view (ideally, not just by fading out, but more cool stuff like flips, etc.).
//when done signing in --> go to the tab bar view
-(IBAction)done:(id)sender {
TabBarController *tabController = [[TabBarController alloc] init];
[UIView beginAnimations:#"removeWithEffect" context:nil];
[UIView setAnimationDuration:4.0];
self.parentViewController.view.frame = CGRectMake(0,0,320,480);
self.parentViewController.view.alpha = 1.0f;
[UIView commitAnimations];
[self.parentViewController.view performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:2.5f];
[self presentModalViewController:tabController animated:YES];
}
Appreciate any help!
That can't work that way. presentModalViewController dislpays the view of a viewController over the own view. It won't replace the source viewController (self).
Since you remove self.parentViewController.view from the view hierarchy, it can't present your tabController modally because you have removed self.
Anyway, i would recommend you another way to achieve your view layout:
Create a tabBarViewController and add its view to a rootView (self.window in the app delegate or whatever you are using now). Then add your login-view to the same view. Due the view hierarchy, the login-view will be displayed above the tabBar.view. And the done button should be implemented this way: (i'm using block syntax for animation as it should be)
-(IBAction)done:(id)sender {
[UIView animateWithDuration:1.0
animations:^{
self.view.frame = CGRectMake(0, 480, 320, 480);
self.view.alpha = 0.0
}
completion:^(BOOL finished){
[self.view removeFromSuperView];
}
];
}
You can animate more things than just the alpha, size or position. Just take a look about animations in the documentation. I guess, you'll be interested in view.transform to commit flip animations. ;)
This is how you have to remove the view after animating it.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelay:2.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:myView];
[UIView setAnimationDidStopSelector:#selector(removeFromSuperview)];
[UIView commitAnimations];
Hope this helps.
Happy coding.

How to hide an UI Element slowly

I have a subView that I want to toggle between hidden and not hidden by a button. How do I fade in the subview and fade it out? For now it just appears immediately and disappear immediately when I toggle the button.
I am wondering what is the easiest way to do this animation.
Thanks
On iOS 4.0+ Apple recommends you use their new, block-based animation methods. Using these, the code would look something like this:
[UIView animateWithDuration:2.0
animations:^{myView.alpha = 0.0;}];
The properties you are animating go inside the block (the ^{...} part). Blocks are sort of like functions, so you can put multiple lines of code inside of them, if you want to animate multiple properties. For example:
[UIView animateWithDuration:0.2
animations:^{
view.alpha = 0.0;
view.backgroundColor = [UIColor redColor];
}];
If you need to perform an action after the animation is complete, use the +animateWithDuration:animations:completion: method (which also uses blocks), for example:
[UIView animateWithDuration:0.2
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];
For more info, check out the UIView Class Reference 'Animations' section and 'Animating Views with Blocks' section.
This is the old pre-4.0 way:
http://objcolumnist.com/2009/07/18/simple-uiview-based-animations-on-the-iphone/
... which has the advantage of being conceptually simple and easy to implement.
float alpha = 1.0; // or 0.0 if it's already visible and you want to fade out
[UIView beginAnimations:#"" context:NULL];
[UIView setAnimationDuration:2.0]; // seconds, not ms. guess how i know?
[mySubView setAlpha:alpha];
[UIView commitAnimations];

UiView Transition inside UIView

this feels like a beginner question, but since I am not able to get it working in the intended-fashion, I am hoping somewhere out there is able to point me in the right direction.
What I am trying to achive is a transition of a view inside a view.
I fundamentally want to replace a view inside a view with another view(controller?!?) 's content.
lets say, I have an image of a book and I want to do a transition inside the book to another page (going from the calendar-view to the detailed daily view for example). I only want the "book-content"(white content area) to be included in that transition, and not the whole book itself(whole screen).
I can do a transition with the same view, no problem, but I dont get it working trying to replace the view with a completly different view.
It didnt matter having the views in seperate viewcontrollers, or all the views in one viewcontroller, so I were not able to get it working yet, but even worse, I am running out of ideas.
So HELP! If please somebody out there could be so kind and tell me what I am doing wrong.
Suggestions also very much appreciated.
Thanks!!
Tom
Maybe you could hide one view then show the other using a UIView Animations block.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view1.view cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view2.view cache:YES];
[UIView setAnimationDuration: 1.5];
[UIView commitAnimations];
view1.view.hidden = YES;
view2.view.hidden = NO;
Edit: Is this what you were looking for?
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[view1 viewWillDisappear:YES];
[view2 viewWillAppear:YES];
view1.view.hidden = YES;
view2.view.hidden = NO;
[view1 viewDidDisappear:YES];
[view2 viewDidAppear:YES];
[UIView commitAnimations];
Or, you could use something like this:
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[view1 removeFromSuperview];
[mySuperview addSubview:view2];
}
completion:nil];
Check out the exchangeSubviewsAtIndex: method in the UIView class. Just set up the 2 views that you want to transition from and to as subviews of another view; then call this method on that parent view.
Suppose you have a view controller with two views, A and B. They have identical frames so they occupy the same space in the controller's view, for your purposes displaying a page of a book. You want to display one and transition to the other.
One way would be to set the alpha property of one to 1.0 (opaque) and the other to 0.0 (transparent). Because this property can be animated you could do a fade from one to the other using a beginAnimations:context/commitAnimations, or use one of the block methods like the docs advise.
Another way would be to animate a change in frame in the two views. Set up the views so that one has a frame such that it is in the right place to display, the other has the same frame but with frame.origin.x equal to frame.size.width - it will be hidden because it is off-screen or hidden behind some other view. Animate the frame in by setting view A's frame.origin.x to -frame.size.width and frame B's frame.origin.x to the display position x origin. Then set (no animation) frame A's frame.origin.x to frame.origin.width again, update its content and you are ready to slide another page in from the right.

iPhone Switch views _KILL ! Problem

i have a problem with switch view between 2 views with nib files !
here my code .
my first page goes to page 2 ! but at page 2 i cant back to first page ! my app go out .. here is my code :
from page 1 to 2 :
#import "HafezViewController.h"
#import "GhazaliateHafez.h"
-(IBAction)gh:(id)sender {
HafezViewController *ghPage = [[HafezViewController alloc] initWithNibName: #"GhazaliateHafez" bundle:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.3];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
[self.view addSubview:ghPage.view];
[UIView commitAnimations];
}
^^^^^^^^^
this code works great !
but from page 2 to back :
#import "GhazaliateHafez.h"
#import "HafezViewController.h"
#implementation GhazaliateHafez
-(IBAction)ghtoIndex:(id)sender {
HafezViewController *back1 = [[HafezViewController alloc] initWithNibName:#"index" bundle:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[self.view addSubview:back1.view];
[UIView commitAnimations];
}
after i tap the back button my app go to crashing ...
whats my problem ?
thank you
You are adding view2 to view1, and then adding a view1 back to view2. When done with View2, simple call self.view.removeFromSuperview and view 1 will be shown again.
Actually, looking at this again, it seems like you might want to look at presentModalViewController to show view 2.
Two thoughts that might help you on the way:
I think you might want to run this through Instruments. Are you leaking memory? You're alloc'ing a view each click, then caching it... are you releasing them?
Would it be easier to have two views that exist separate from this, in an array for example, then index the one you want to make active and wrap that into the animation loop above while releasing and hiding the other one? Not quite sure how to make the other view go away on command as release is garbage controlled... but I know there is a way to do it.
And this is from a post from earlier that helped me when I was asking how to remove a subview immediately:
myGroovySubview.hidden = YES; hides the view. You could also try to remove it from its superview with [myGroovySubview removeFromSuperview];
If you removed it from its superview, the release call should automatically remove it from memory since the reference count should be zero after that call.