3 回答
TA贡献1784条经验 获得超2个赞
根据一些评论,原始答案中的解决方案在iOS 8+中的某些情况下似乎不起作用。如果没有更多详细信息,我无法验证实际情况。
对于那些在那种情况下的人,还有另一种选择。可以通过覆盖检测何时弹出视图控制器willMove(toParentViewController:)。基本思想是在parentis 时弹出视图控制器nil。
请查看“实现Container View Controller”以了解更多详细信息。
从iOS 5开始,我发现处理这种情况的最简单方法是使用新方法- (BOOL)isMovingFromParentViewController:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController) {
// Do your stuff here
}
}
- (BOOL)isMovingFromParentViewController 当您在导航堆栈中推入和弹出控制器时很有意义。
但是,如果要呈现模式视图控制器,则应- (BOOL)isBeingDismissed改用:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isBeingDismissed) {
// Do your stuff here
}
}
如本问题所述,您可以结合使用以下两个属性:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController || self.isBeingDismissed) {
// Do your stuff here
}
}
其他解决方案依赖于的存在UINavigationBar。相反,更喜欢我的方法,因为它使执行任务所需的任务与触发事件的操作(即按后退按钮)分离。
TA贡献1788条经验 获得超4个赞
虽然viewWillAppear()和viewDidDisappear() 被当返回按钮被窃听叫,它们也被称为在其他时间。有关更多信息,请参见答案结尾。
使用UIViewController.parent
当借助willMoveToParentViewController(_:)OR 将VC从其父级(NavigationController)中删除时,最好检测到后退按钮didMoveToParentViewController()
如果parent为零,则将视图控制器从导航堆栈中弹出并关闭。如果parent不为nil,则将其添加到堆栈中并显示。
// Objective-C
-(void)willMoveToParentViewController:(UIViewController *)parent {
[super willMoveToParentViewController:parent];
if (!parent){
// The back button was pressed or interactive gesture used
}
}
// Swift
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
// The back button was pressed or interactive gesture used
}
}
换出willMove了didMove和检查self.parent做工作后视图控制器被驳回。
停止解雇
请注意,如果需要执行某种异步保存,则检查父级不允许您“暂停”过渡。为此,您可以实现以下内容。唯一的缺点是,您失去了精美的iOS样式/动画后退按钮。在此处也要小心使用交互式滑动手势。使用以下内容处理这种情况。
var backButton : UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
// Disable the swipe to make sure you get your chance to save
self.navigationController?.interactivePopGestureRecognizer.enabled = false
// Replace the default back button
self.navigationItem.setHidesBackButton(true, animated: false)
self.backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
self.navigationItem.leftBarButtonItem = backButton
}
// Then handle the button selection
func goBack() {
// Here we just remove the back button, you could also disabled it or better yet show an activityIndicator
self.navigationItem.leftBarButtonItem = nil
someData.saveInBackground { (success, error) -> Void in
if success {
self.navigationController?.popViewControllerAnimated(true)
// Don't forget to re-enable the interactive gesture
self.navigationController?.interactivePopGestureRecognizer.enabled = true
}
else {
self.navigationItem.leftBarButtonItem = self.backButton
// Handle the error
}
}
}
将显示更多视图
如果您没有遇到viewWillAppear viewDidDisappear问题,我们来看一个例子。假设您有三个视图控制器:
ListVC:事物的表视图
DetailVC:关于事物的详细信息
SettingsVC:某些选项
detailVC当您从listVC转到settingsVC并返回到时,可以跟踪上的呼叫listVC
列表>详细信息(按下detailVC)Detail.viewDidAppear<-出现
详细信息>设置(按下settingsVC)Detail.viewDidDisappear<-消失
然后回头...
设置>详细信息(弹出设置 VC)<- Detail.viewDidAppear出现
详细信息>列表(弹出详细信息 VC)Detail.viewDidDisappear<-消失
请注意,viewDidDisappear不仅在返回时,而且在前进时,都会多次调用它。对于可能需要的快速操作,但是对于更复杂的操作(例如要保存的网络呼叫),可能不需要。
TA贡献1802条经验 获得超6个赞
第一种方法
- (void)didMoveToParentViewController:(UIViewController *)parent
{
if (![parent isEqual:self.parentViewController]) {
NSLog(@"Back pressed");
}
}
第二种方法
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
}
[super viewWillDisappear:animated];
}
- 3 回答
- 0 关注
- 768 浏览
添加回答
举报