Ben*_*ard 105 cocoa-touch uiviewcontroller uiview uiviewanimation ios
当使用时解除模态视图控制器时dismissViewController,可以选择提供完成块.是否有相似的等价物popViewController?
完成论证非常方便.例如,我可以使用它来阻止从tableview中删除一行,直到模态关闭屏幕,让用户看到行动画.从推出的视图控制器返回时,我想要同样的机会.
我已经尝试放置popViewController一个UIView动画块,我可以访问完成块.但是,这会对弹出的视图产生一些不必要的副作用.
如果没有这样的方法,有什么办法吗?
Jor*_*ers 186
我知道两年前已经接受了答案,但这个答案是不完整的.
没有办法做你想要开箱即用的东西
这在技术上是正确的,因为UINavigationControllerAPI不提供任何选项.但是,通过使用CoreAnimation框架,可以向底层动画添加完成块:
[CATransaction begin];
[CATransaction setCompletionBlock:^{
// handle completion here
}];
[self.navigationController popViewControllerAnimated:YES];
[CATransaction commit];
Run Code Online (Sandbox Code Playgroud)
一旦popViewControllerAnimated:结束使用动画,就会调用完成块.此功能自iOS 4开始提供.
Hot*_*ard 50
对于iOS9 SWIFT版本 - 就像一个魅力(没有测试过早期版本).基于这个答案
extension UINavigationController {
func pushViewController(viewController: UIViewController, animated: Bool, completion: () -> ()) {
pushViewController(viewController, animated: animated)
if let coordinator = transitionCoordinator() where animated {
coordinator.animateAlongsideTransition(nil) { _ in
completion()
}
} else {
completion()
}
}
func popViewController(animated: Bool, completion: () -> ()) {
popViewControllerAnimated(animated)
if let coordinator = transitionCoordinator() where animated {
coordinator.animateAlongsideTransition(nil) { _ in
completion()
}
} else {
completion()
}
}
}
Run Code Online (Sandbox Code Playgroud)
Arb*_*tur 30
我Swift用@JorisKluivers答案制作了一个扩展版本.
动画,是您在完成后这将调用完成关闭push和pop.
extension UINavigationController {
func popViewControllerWithHandler(completion: ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.popViewControllerAnimated(true)
CATransaction.commit()
}
func pushViewController(viewController: UIViewController, completion: ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.pushViewController(viewController, animated: true)
CATransaction.commit()
}
}
Run Code Online (Sandbox Code Playgroud)
小智 16
我遇到过同样的问题.因为我必须在多个场合使用它,并且在完成块的链中,我在UINavigationController子类中创建了这个通用解决方案:
- (void) navigationController:(UINavigationController *) navigationController didShowViewController:(UIViewController *) viewController animated:(BOOL) animated {
if (_completion) {
_completion();
_completion = nil;
}
}
- (UIViewController *) popViewControllerAnimated:(BOOL) animated completion:(void (^)()) completion {
_completion = completion;
return [super popViewControllerAnimated:animated];
}
Run Code Online (Sandbox Code Playgroud)
假设
@interface NavigationController : UINavigationController <UINavigationControllerDelegate>
Run Code Online (Sandbox Code Playgroud)
和
@implementation NavigationController {
void (^_completion)();
}
Run Code Online (Sandbox Code Playgroud)
和
- (id) initWithRootViewController:(UIViewController *) rootViewController {
self = [super initWithRootViewController:rootViewController];
if (self) {
self.delegate = self;
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
mat*_*way 15
没有办法做你想要开箱即用的东西.即,没有用于从导航堆栈弹出视图控制器的完成块的方法.
我要做的就是把逻辑放进去viewDidAppear.当视图完成屏幕时,将调用该方法.它将被视为出现视图控制器的所有不同场景,但这应该没问题.
或者您可以使用该UINavigationControllerDelegate方法navigationController:didShowViewController:animated:执行类似的操作.当导航控制器完成推送或弹出视图控制器时调用此方法.
rsh*_*hev 13
正确使用或不使用动画,还包括popToRootViewController:
// updated for Swift 3.0
extension UINavigationController {
private func doAfterAnimatingTransition(animated: Bool, completion: @escaping (() -> Void)) {
if let coordinator = transitionCoordinator, animated {
coordinator.animate(alongsideTransition: nil, completion: { _ in
completion()
})
} else {
DispatchQueue.main.async {
completion()
}
}
}
func pushViewController(viewController: UIViewController, animated: Bool, completion: @escaping (() -> Void)) {
pushViewController(viewController, animated: animated)
doAfterAnimatingTransition(animated: animated, completion: completion)
}
func popViewController(animated: Bool, completion: @escaping (() -> Void)) {
popViewController(animated: animated)
doAfterAnimatingTransition(animated: animated, completion: completion)
}
func popToRootViewController(animated: Bool, completion: @escaping (() -> Void)) {
popToRootViewController(animated: animated)
doAfterAnimatingTransition(animated: animated, completion: completion)
}
}
Run Code Online (Sandbox Code Playgroud)
Muh*_*qas 12
SWIFT 4.1
extension UINavigationController {
func pushToViewController(_ viewController: UIViewController, animated:Bool = true, completion: @escaping ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.pushViewController(viewController, animated: animated)
CATransaction.commit()
}
func popViewController(animated:Bool = true, completion: @escaping ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.popViewController(animated: animated)
CATransaction.commit()
}
func popToViewController(_ viewController: UIViewController, animated:Bool = true, completion: @escaping ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.popToViewController(viewController, animated: animated)
CATransaction.commit()
}
func popToRootViewController(animated:Bool = true, completion: @escaping ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.popToRootViewController(animated: animated)
CATransaction.commit()
}
}
Run Code Online (Sandbox Code Playgroud)
基于@ HotJard的答案,当你想要的只是几行代码.快捷方便.
斯威夫特4:
_ = self.navigationController?.popViewController(animated: true)
self.navigationController?.transitionCoordinator.animate(alongsideTransition: nil) { _ in
doWantIWantAfterContollerHasPopped()
}
Run Code Online (Sandbox Code Playgroud)
根据这个答案清理了Swift 4版本。
extension UINavigationController {
func pushViewController(_ viewController: UIViewController, animated: Bool, completion: @escaping () -> Void) {
self.pushViewController(viewController, animated: animated)
self.callCompletion(animated: animated, completion: completion)
}
func popViewController(animated: Bool, completion: @escaping () -> Void) -> UIViewController? {
let viewController = self.popViewController(animated: animated)
self.callCompletion(animated: animated, completion: completion)
return viewController
}
private func callCompletion(animated: Bool, completion: @escaping () -> Void) {
if animated, let coordinator = self.transitionCoordinator {
coordinator.animate(alongsideTransition: nil) { _ in
completion()
}
} else {
completion()
}
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 3回答,感谢这个答案:https://stackoverflow.com/a/28232570/3412567
//MARK:UINavigationController Extension
extension UINavigationController {
//Same function as "popViewController", but allow us to know when this function ends
func popViewControllerWithHandler(completion: @escaping ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.popViewController(animated: true)
CATransaction.commit()
}
func pushViewController(viewController: UIViewController, completion: @escaping ()->()) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.pushViewController(viewController, animated: true)
CATransaction.commit()
}
}
Run Code Online (Sandbox Code Playgroud)
如果你有这个...
navigationController?.popViewController(animated: false)
nextStep()
Run Code Online (Sandbox Code Playgroud)
而你想添加一个完成...
CATransaction.begin()
navigationController?.popViewController(animated: true)
CATransaction.setCompletionBlock({ [weak self] in
self?.nextStep() })
CATransaction.commit()
Run Code Online (Sandbox Code Playgroud)
就这么简单。
请参考最新版本(5.1)的Swifty和类似SDK的方式,
extension UINavigationController {
func popViewController(animated: Bool, completion: (() -> ())? = nil) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
popViewController(animated: animated)
CATransaction.commit()
}
func pushViewController(_ viewController: UIViewController, animated: Bool, completion: (() -> ())? = nil) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
pushViewController(viewController, animated: animated)
CATransaction.commit()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
48902 次 |
| 最近记录: |