可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
As everyone know the UINavigationController push a ViewController from Left To Right, is there a way to push the View from Right To Left? like the animation for the back button.
For now I have this:
[self.navigationController pushViewController:viewController animated:YES];
回答1:
You can create a NSMutableArray
from the navigationController's array of viewcontrollers
and insert new viewController before the current one. Then set the viewControllers array without animation and pop back.
UIViewController *newVC = ...;
NSMutableArray *vcs = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[vcs insertObject:newVC atIndex:[vcs count]-1];
[self.navigationController setViewControllers:vcs animated:NO];
[self.navigationController popViewControllerAnimated:YES];
回答2:
Please try this one
HomePageController *pageView = [[HomePageController alloc] initWithNibName:@"HomePageController_iPhone" bundle:nil];
CATransition *transition = [CATransition animation];
transition.duration = 0.45;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
transition.delegate = self;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
self.navigationController.navigationBarHidden = NO;
[self.navigationController pushViewController:pageView animated:NO];
回答3:
Try this :
//Push effect in reverse way
CATransition* transition = [CATransition animation];
transition.duration = 0.75;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:vc animated:NO];
回答4:
This code is working fine. Please try
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionReveal;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[self.navigationController pushViewController:phoneServicesViewController animated:NO];
回答5:
You seem to want to "pop back". This can be achieved by three methods on your UINavigationController
instance:
To come back to the "root" controller:
-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated
Or to come back to one of the previous controllers :
-(NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
Or to come back to the previously pushed controller :
-(UIViewController *)popViewControllerAnimated:(BOOL)animated
回答6:
No, right to left is reserved for popping viewcontrollers from the navigation stack. You can however get such an effect by animating the views yourself. Something like:
[UIView beginAnimations:@"rightToLeft" context:NULL];
CGRect newFrame = aView.frame;
newFrame.origin.x -= newFrame.size.width;
aView.frame = newFrame;
[UIView commitAnimations];
This will however not do anything to your navigation controller.
回答7:
Just an improvement of the best answer here in my opinion:
UIViewController *newVC = ...;
[self.navigationController setViewControllers:@[newVC, self] animated:NO];
[self.navigationController popViewControllerAnimated:YES];
And to go back to the initial controller, just do a push to it.
回答8:
I had the same problem, this is how I solved it
[self.navigationController popViewControllerAnimated:YES];
This will resemble "going back" i.e a situation where a back button is clicked and you navigate to the previous page
回答9:
Based on @felixlam 's answer, I upgraded and created a "reverse" direction navigation controller that overrides the default push / pop methods to act like this.
class LeftPushNavigationController: BaseNavigationController {
override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.isEnabled = false
}
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
// If the push is not animated, simply pass to parent
guard animated else { return super.pushViewController(viewController, animated: animated) }
// Setup back button
do {
// Hide original back button
viewController.navigationItem.setHidesBackButton(true, animated: false)
// Add new one
viewController.navigationItem.rightBarButtonItem = UIBarButtonItem(
image: #imageLiteral(resourceName: "iconBackReverse"),
style: .plain,
target: self,
action: #selector(self.pop)
)
}
// Calculate final order
let finalVCs = self.viewControllers + [viewController]
// Insert the viewController to the before-last position (so it can be popped to)
var viewControllers = self.viewControllers
viewControllers.insert(viewController, at: viewControllers.count - 1)
// Insert viewcontroller before the last one without animation
super.setViewControllers(viewControllers, animated: false)
// Pop with the animation
super.popViewController(animated: animated)
// Set the right order without animation
super.setViewControllers(finalVCs, animated: false)
}
override func popViewController(animated: Bool) -> UIViewController? {
// If the push is not animated, simply pass to parent
guard animated else { return super.popViewController(animated: animated) }
guard self.viewControllers.count > 1 else { return nil }
// Calculate final order
var finalVCs = self.viewControllers
let viewController = finalVCs.removeLast()
// Remove the parent ViewController (so it can be pushed)
var viewControllers = self.viewControllers
let parentVC = viewControllers.remove(at: viewControllers.count - 2)
// Set the viewcontrollers without the parent & without animation
super.setViewControllers(viewControllers, animated: false)
// Create push animation with the parent
super.pushViewController(parentVC, animated: animated)
// Set the right final order without animation
super.setViewControllers(finalVCs, animated: false)
// Return removed viewController
return viewController
}
@objc
private func pop() {
_ = popViewController(animated: true)
}
}