In the typical viewcontroller transition both views, the disappear and appear view are moving, but now I want to create a custom animation where you throw the event to change of view, the view that will disappear, just hide without transition and animation, and the view will appear continue with the same transition.
then the problem here is I have navigation bar and I don't know, how can I create a custom transition of navigation bar?,
can you help me to know how to change or remove the transition of navigation controller.
I've try it but it only add other transition and don't remove the base transition.
For Push:
MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.navigationController pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
For Pop:
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:self.navigationController.view cache:NO];
}];
[self.navigationController popViewControllerAnimated:NO];
any ideas? thanks :D
You can just use add as subview and have title bar to mimic like navigation controller.
MainView *nextView = [[MainView alloc] init];
//setup frame
nextView.view.frame = xxx;
[self.view addSubview:nextView.view];
Remove using [nexView.view removeFromSuperView];
OR
Just add some view above your current view with default hidden and set hidden NO on some action or call bringSubviewFront method if you want to keep view below and bring in front on some action.
Related
I just tried my making a custom transition between view controllers. It basically spins the next one into view, and it works. Except that the source view controller flickers briefly back into visibility right as the animation completes, just as the destination view controller achieves its final position.
I'm also getting a warning about Unbalanced calls to begin/end appearance transitions which I'm still working on fixing-- I don't know if they're related.
Does anyone see anything here that jumps out as not quite right that would cause a flicker?
I then just assigned a button to do a custom segue via storyboard editor.
-(void)perform
{
UIViewController *source = self.sourceViewController;
UIViewController *destination = self.destinationViewController;
[source.view addSubview:destination.view];
destination.view.transform = CGAffineTransformMakeRotation(M_PI / 2);
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
destination.view.transform = CGAffineTransformMakeRotation(0);
}completion:^(BOOL finished){
[destination.view removeFromSuperview];
[source presentViewController:destination animated:NO completion:NULL];
}];
}
Take out the removeFromSuperview.
I am using a custom unwind segue in a navigation controller, in the animation of the segue the navigation bar is not visible during the animation, when the animation ends the navigation bar 'pops'. ¿How can i retain the visibility of the navigation bar during the animation?
More details:
I have a button in the navigation bar that calls modal view this animation performs as expected, the new view has a button to trigger the unwind segue animation the view to grow and disappear, while this animation is performing the Navigation Bar in the destination view controller is not visible until the animation is finished.
This is the code i'm using for the custom segue.
- (void) perform {
UIViewController *sourceViewcontroller = self.sourceViewController;
UIViewController *destinationViewcontroller = self.destinationViewController;
[sourceViewcontroller.view.superview insertSubview:destinationViewcontroller.view atIndex:0];
[destinoViewcontroller beginAppearanceTransition:YES animated:YES];
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
origenViewcontroller.view.transform = CGAffineTransformMakeScale(1.5, 1.5);
origenViewcontroller.view.alpha = 0.0;
}
completion:^(BOOL finished){
[destinationViewcontroller.view removeFromSuperview];
[sourceViewcontroller dismissViewControllerAnimated:NO completion:NULL];
}];
}
Ok, so i think i got it, what i did was inserting the whole navigation controller view in the superview of the source view and removing the code to remove the destination view from the superview and setting to YES the option of dismissViewControllerAnimated like this:
- (void) perform {
UIViewController *origenViewcontroller = self.sourceViewController;
UIViewController *destinoViewcontroller = self.destinationViewController;
[origenViewcontroller.view.superview insertSubview:destinoViewcontroller.navigationController.view atIndex:0];
[UIView animateWithDuration:0.4
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
origenViewcontroller.view.transform = CGAffineTransformMakeScale(2.0, 2.0);
origenViewcontroller.view.alpha = 0.0;
}
completion:^(BOOL finished){
[origenViewcontroller dismissViewControllerAnimated:YES completion:NULL];
}];
}
I'm still not sure if this is the correct way to do it.
You could embed the destinationViewController in a UINavigationController too and set your segue from the sourceViewController to the Navigation Controller.
This is typical question and possibly duplicated, but..
There is iPad app which has UINavigationBar and UITabBar. I have created a button on navigationBar which must show appinfoViewController.
When I present it navigationBar and tabTab are still available to tap. But I would like to show appinfoViewController to full app's main screen size (like modal)
This is my code:
- (void)showInfo
{
AboutViewController *about = [[AboutViewController alloc] init];
[about.view setFrame: self.view.frame];
[about.view setAlpha:0.0];
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
[about.view setAlpha:1.0];
[self.view addSubview:about.view];
[self addChildViewController:about];
[about didMoveToParentViewController:self];
}
completion:^(BOOL finished){
}];
}
How to present appinfoViewController to full screen?
May be it's possible to present it modally but without BLACK background?
As suggested in the comments, using
[self presentViewController:about animated:YES completion:nil]
would get rid of the nav bar and the tab bar. If you need to keep them, you need to use
[self.navigationController pushViewController:about animated:YES];
EDIT:
In order to have the user interaction disabled everywhere except for your about view, it's slightly trickier: first off, you need to have all of your UI elements embedded in a view that is not the main view of your presenting view controller.
Let's say you have only a button (the "show about" button), you wouldn't just place it in your main view, but you would use another view (let's call it "outer view") that is just as big as the view controller's view and where you place the button (along with any other ui element you might have). You also need an outlet to this outer view. Then write a method such as:
-(void)userInteractionEnabled:(BOOL)enabled
{
self.navigationController.navigationBar.userInteractionEnabled = enabled;
self.tabBarController.tabBar.userInteractionEnabled = enabled;
self.outerView.userInteractionEnabled = enabled;
}
Alternatively you could simply disable every "interactive" outlet instead of outerView. So if, for example, you have 2 textviews, 3 buttons and one UIPickerView, you would set userInteractionEnabled = enabled for each of those outlets (instead of doing it only for the parent view).
Now, in your showInfo method you can have:
CGRect frame = CGRectMake(50, 50, 200, 200); //Use whatever origin and size you need
about.view.frame = frame;
[self.view addSubview:about.view];
[self userInteractionEnabled:NO]
And in your btnClose method you can just put:
[about.view removeFromSuperview];
[self userInteractionEnabled:YES];
I hope this helps, let me know if this is what you needed!
P.S. Maybe you're already aware of this, but there is a class UIPopoverController, only available for iPad's apps, that would pretty much do all of this for you. You can find a tutorial on how to use it here.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
AboutViewController *about = (AboutViewController *)[storyBoard instantiateViewControllerWithIdentifier:#"about"];
[self.navigationController pushViewController:about animated:YES];
You can add viewcontroller view layer directly to presenting viewcontroller view.
Code should be look like --
AboutViewController *about = [[AboutViewController alloc] init];
[about.view setFrame: self.view.bound];
[about.view setAlpha:0.0];
[self.view addSubview:about.view];
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
[about.view setAlpha:1.0];
}
completion:^(BOOL finished){
}];
How is it possible that I change the transition for presenting a modal view controller. Is it possible that the presenting transition is using the default UIModalTransitionStyle....
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
but the dismiss transition is using the UIViewAnimationTransitionCurlUp transition. Important is that I don't want to use the UIModalTransitionStylePartialCurl it should be the CurlUp one.
Sadly the following code doesn't work:
[UIView transitionFromView:self.view toView:self.parentViewController.parentViewController.parentViewController.view duration:1.0 options:UIViewAnimationTransitionCurlUp completion:^(BOOL finished) {....}];
Maybe it has something to do that the view controller is displayed in modal mode.
It would be nice if someone can help.
It feels kludgy, but you can do this by animating the transition of adding your destination view controller's view, but on the completion of that, you immediately remove it again and then properly transition to it via the presentViewController (this time without animation, since the visual effect has already been rendered).
I do this in a subclassed custom UIStoryboardSegue (you didn't say NIBs or storyboard, but the concept is the same):
- (void)perform
{
UIViewController *src = self.sourceViewController;
UIViewController *dst = self.destinationViewController;
[UIView transitionWithView:src.navigationController.view
duration:0.75
options:UIViewAnimationOptionTransitionCurlUp | UIViewAnimationOptionCurveEaseInOut
animations:^{
[src.navigationController.view addSubview:dst.view];
}
completion:^(BOOL finished){
[dst.view removeFromSuperview];
[src presentViewController:dst animated:NO completion:nil];
}];
}
Clearly, if your source view controller doesn't have a navigation controller, you would replace those "src.navigationController.view" with just "src.view". But hopefully this gives you the idea.
And, anticipating the logical follow-up question, when dismissing the view controller, I have a button hooked up to an IBAction:
- (IBAction)doneButton:(id)sender
{
[UIView transitionWithView:self.view.superview
duration:0.75
options:UIViewAnimationOptionTransitionCurlDown
animations:^{
[self dismissViewControllerAnimated:NO completion:nil];
}
completion:nil];
}
I find myself in need of access to a viewcontroller from its view.
Here is the method
-(void)changePageView:(UIViewController*)newviewcont withtransitiontype:(int)t andtransitionspeed:(int)s
{
//Remove whatever view is currently loaded at index 0, this index is only to be used by "page" views
UIView *oldview = [self.view.subviews objectAtIndex:0];
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:s];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[newviewcont viewWillAppear:YES];
//[oldview viewWillDisappear:YES];
[oldview removeFromSuperview];
[self.view insertSubview:newviewcont.view atIndex:0];
//[oldview viewDidDisappear:YES];
[newviewcont viewDidAppear:YES];
}
Basically, I am trying to write a generic view switch method that is called by the root controller to swap out subviewcontorllers views from the rootcontrollers view.
I pass in a subviewcontroller and am able to remove the current subview. But in order to do proper view switching animation i need access to the current views view controller. Is this the wrong approach and can it be done?
I added a member to the rootcontroller that hold onto the current sub view controller (currentController) and refers to it when a controller swap is done
-(void)changePageView:(UIViewController*)newviewcont withtransitiontype:(int)t andtransitionspeed:(int)s
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:s];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[newviewcont viewWillAppear:YES];
[self.currentController viewWillDisappear:YES];
[self.currentController.view removeFromSuperview];
[self.view insertSubview:newviewcont.view atIndex:0];
[self.currentController viewDidDisappear:YES];
[newviewcont viewDidAppear:YES];
[UIView commitAnimations];
self.currentController = newviewcont;
}
The changeView() method belongs in the viewcontroller. It would solve you problem of having the view knowing about it's controller (which it shouldn't) and it makes more sense.
Also unless you are doing something fancy in changeView() that can't be done using the methods in a UIViewController object then you should just use it instead, if it is neccesary to implement your own view switching method then you can extend UIViewController instead of implemtning part of the view controlelr in your view.
my 2 cents :)
I believe your approach is wrong. You should look into UINavigationController I believe.