众所周知,UINavigationController从左到右推送ViewController,有没有办法将视图从右推到左?就像后退按钮的动画一样 现在我有这个:
[self.navigationController pushViewController:viewController animated:YES];
答案 0 :(得分:52)
您可以从navigationController的NSMutableArray
数组中创建viewcontrollers
,并在当前版本之前插入新的viewController。然后设置viewControllers数组没有动画并弹回。
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];
答案 1 :(得分:36)
请尝试这个
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];
答案 2 :(得分:9)
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];
答案 3 :(得分:6)
此代码工作正常。请尝试
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];
答案 4 :(得分:2)
不,从右到左保留用于从导航堆栈中弹出viewcontrollers。但是,您可以通过自己设置动画来获得此类效果。类似的东西:
[UIView beginAnimations:@"rightToLeft" context:NULL];
CGRect newFrame = aView.frame;
newFrame.origin.x -= newFrame.size.width;
aView.frame = newFrame;
[UIView commitAnimations];
但是这对导航控制器没有任何作用。
答案 5 :(得分:2)
你似乎想“回弹”。这可以通过UINavigationController
实例上的三种方法来实现:
回到“根”控制器:
-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated
或者回到以前的控制器之一:
-(NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
或者回到之前推出的控制器:
-(UIViewController *)popViewControllerAnimated:(BOOL)animated
答案 6 :(得分:2)
在我看来,这是对最佳答案的改进:
UIViewController *newVC = ...;
[self.navigationController setViewControllers:@[newVC, self] animated:NO];
[self.navigationController popViewControllerAnimated:YES];
要回到初始控制器,只需按一下即可。
答案 7 :(得分:1)
基于@felixlam的回答,我升级并创建了一个“反向”方向导航控制器,它会覆盖默认的推/弹方法,就像这样。
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)
}
}
答案 8 :(得分:0)
我有同样的问题,这就是我解决的问题
[self.navigationController popViewControllerAnimated:YES];
这将类似于"返回"即单击后退按钮并导航到上一页的情况
答案 9 :(得分:0)
Swift 4.2
let pageView = TaskFolderListViewController.init(nibName: "HomePageController_iPhone", bundle: nil)
let transition = CATransition()
transition.duration = 0.45
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromLeft
self.navigationController?.view.layer.add(transition, forKey: kCATransition)
self.navigationController?.pushViewController(pageView, animated: false)
答案 10 :(得分:0)
根据先前的最佳答案,您可以进行UINavigationController
扩展并按以下方式保留导航堆栈:
extension UINavigationController {
/// Pushes view controller into navigation stack with backwards animation.
func pushBackwards(viewController newViewController: UIViewController) {
if let currentController = viewControllers.last {
let previousControllers = viewControllers[0..<viewControllers.endIndex-1]
var controllers = Array(previousControllers + [newViewController, currentController])
setViewControllers(controllers, animated: false)
popViewController(animated: true)
// Adjusting the navigation stack
_ = controllers.popLast()
controllers.insert(currentController, at: controllers.count-1)
setViewControllers(controllers, animated: false)
} else {
// If there is no root view controller, set current one without animation.
setViewControllers([newViewController], animated: false)
}
}
}