ビューをナビゲーション コントローラーにプッシュしました。戻るボタンを押すと、前のビューに自動的に移動します。ビューをスタックからポップする前に、戻るボタンが押されたときにいくつかのことをしたいと思います。戻るボタンのコールバック関数はどれですか?
12 に答える
William Jockusch の答えは、この問題を簡単なトリックで解決します。
-(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];
}
私の意見では、最善の解決策です。
- (void)didMoveToParentViewController:(UIViewController *)parent
{
if (![parent isEqual:self.parentViewController]) {
NSLog(@"Back pressed");
}
}
ただし、iOS5以降でのみ動作します
ユーザーの確認などのためにビューがポップされる前にイベントを処理できるように、戻るボタンをオーバーライドすることをお勧めします。
viewDidLoad で UIBarButtonItem を作成し、sel を渡して self.navigationItem.leftBarButtonItem を設定します
- (void) viewDidLoad
{
// change the back button to cancel and add an event handler
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@”back”
style:UIBarButtonItemStyleBordered
target:self
action:@selector(handleBack:)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
}
- (void) handleBack:(id)sender
{
// pop to root view controller
[self.navigationController popToRootViewControllerAnimated:YES];
}
次に、UIAlertView を発生させてアクションを確認し、View Controller をポップするなどの操作を実行できます。
または、新しい戻るボタンを作成する代わりに、UINavigationController デリゲート メソッドに従って、戻るボタンが押されたときにアクションを実行できます。
私はこの解決策で終わります。戻るボタンをタップすると、viewDidDisappear メソッドが呼び出されます。true を返す isMovingFromParentViewController セレクターを呼び出して確認できます。(Delegate を使用して) データを返すことができます。これが誰かの助けになることを願っています。
-(void)viewDidDisappear:(BOOL)animated{
if (self.isMovingToParentViewController) {
}
if (self.isMovingFromParentViewController) {
//moving back
//pass to viewCollection delegate and update UI
[self.delegateObject passBackSavedData:self.dataModel];
}
}
これは、これを検出する正しい方法です。
- (void)willMoveToParentViewController:(UIViewController *)parent{
if (parent == nil){
//do stuff
}
}
このメソッドは、ビューがプッシュされたときにも呼び出されます。したがって、parent==nil をチェックすると、View Controller がスタックからポップされます
「スタックからビューをポップする前に」の場合:
- (void)willMoveToParentViewController:(UIViewController *)parent{
if (parent == nil){
NSLog(@"do whatever you want here");
}
}
viewController に問い合わせるよりも適切な方法があります。コントローラーを、戻るボタンを持つ navigationBar のデリゲートにすることができます。これが例です。戻るボタンの押下を処理するコントローラーの実装で、UINavigationBarDelegate プロトコルを実装することを伝えます。
@interface MyViewController () <UINavigationBarDelegate>
次に、初期化コードのどこか (おそらく viewDidLoad 内) で、コントローラーをナビゲーション バーのデリゲートにします。
self.navigationController.navigationBar.delegate = self;
最後に、shouldPopItem メソッドを実装します。このメソッドは、戻るボタンが押されたときに呼び出されます。スタック内に複数のコントローラーまたはナビゲーション アイテムがある場合、ポップされているナビゲーション アイテム (item パラメーター) を確認して、必要なときにのみカスタム操作を行うようにする必要があります。次に例を示します。
-(BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
NSLog(@"Back button got pressed!");
//if you return NO, the back button press is cancelled
return YES;
}
これが私が実装した別の方法です(アンワインドセグエでテストしませんでしたが、このページの他のソリューションに関して他の人が述べているように、おそらく区別されません)、子VCがプッシュされる前に親View Controllerにアクションを実行させますビュー スタックから取り出されます (元の UINavigationController から数レベル下で使用しました)。これは、childVC がプッシュされる前にアクションを実行するためにも使用できます。これには、カスタムの UIBarButtonItem または UIButton を作成する代わりに、iOS システムの戻るボタンを操作できるという利点があります。
親 VC に
UINavigationControllerDelegate
プロトコルを採用させ、デリゲート メッセージを登録してもらいます。MyParentViewController : UIViewController <UINavigationControllerDelegate> -(void)viewDidLoad { self.navigationcontroller.delegate = self; }
UINavigationControllerDelegate
このインスタンス メソッドを に実装しMyParentViewController
ます。- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { // Test if operation is a pop; can also test for a push (i.e., do something before the ChildVC is pushed if (operation == UINavigationControllerOperationPop) { // Make sure it's the child class you're looking for if ([fromVC isKindOfClass:[ChildViewController class]]) { // Can handle logic here or send to another method; can also access all properties of child VC at this time return [self didPressBackButtonOnChildViewControllerVC:fromVC]; } } // If you don't want to specify a nav controller transition return nil; }
上記の
UINavigationControllerDelegate
インスタンスメソッドに特定のコールバック関数を指定すると-(id <UIViewControllerAnimatedTransitioning>)didPressBackButtonOnAddSearchRegionsVC:(UIViewController *)fromVC { ChildViewController *childVC = ChildViewController.new; childVC = (ChildViewController *)fromVC; // childVC.propertiesIWantToAccess go here // If you don't want to specify a nav controller transition return nil;
}
「viewWillDisappear」または同様のメソッドを使用できない場合は、UINavigationController をサブクラス化してみてください。これはヘッダークラスです:
#import <Foundation/Foundation.h>
@class MyViewController;
@interface CCNavigationController : UINavigationController
@property (nonatomic, strong) MyViewController *viewController;
@end
実装クラス:
#import "CCNavigationController.h"
#import "MyViewController.h"
@implementation CCNavigationController {
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
@"This is the moment for you to do whatever you want"
[self.viewController doCustomMethod];
return [super popViewControllerAnimated:animated];
}
@end
一方、このviewControllerをカスタムNavigationControllerにリンクする必要があるため、通常のviewControllerのviewDidLoadメソッドで次のようにします。
@implementation MyViewController {
- (void)viewDidLoad
{
[super viewDidLoad];
((CCNavigationController*)self.navigationController).viewController = self;
}
}
ストーリーボードを使用していて、プッシュ セグエから来ている場合は、オーバーライドすることもできますshouldPerformSegueWithIdentifier:sender:
。