ペーストボードをチェックして、ビューが表示されたときに特定の値が含まれている場合にアラートを表示したい。コードをviewDidLoad
に配置して、1回だけ呼び出されるようにすることができますが、問題はアラートビューの表示が速すぎることです。タイマーを設定してアラートの表示を延期できることはわかっていますが、これは適切な回避策ではないと思います。
私は質問 iOS 7-viewDidLoadとviewDidAppearの違い を確認しましたが、ビューが存在するかどうかを確認するためのステップが1つあることを発見しました。これを行うためのAPIはあるのでしょうか。
更新:「1回のみ」とは、ビューコントローラーインスタンスの存続期間を意味します。
これに使用できる標準の組み込みメソッドがあります。
Objective-C:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([self isBeingPresented] || [self isMovingToParentViewController]) {
// Perform an action that will only be done once
}
}
スウィフト3:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.isBeingPresented || self.isMovingToParentViewController {
// Perform an action that will only be done once
}
}
isBeingPresented
の呼び出しは、モーダルで表示された結果としてビューコントローラーが最初に表示されたときにtrueになります。 isMovingToParentViewController
は、ビューコントローラーが最初にナビゲーションスタックにプッシュされるときにtrueになります。 2つのうちの1つは、ビューコントローラが初めて表示されたときにtrueになります。
最初の呼び出しを追跡するために、BOOL
ivarsやその他のトリックに対処する必要はありません。
rmaddyの答えは本当に良いですが、ビューコントローラーがナビゲーションコントローラーのルートビューコントローラーであり、他のすべてのコンテナーがこれらのフラグを子ビューコントローラーに渡さない場合、問題は解決しません。
したがって、このような状況では、フラグを使用して後で使用するのが最善です。
@interface SomeViewController()
{
BOOL isfirstAppeareanceExecutionDone;
}
@end
@implementation SomeViewController
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if(isfirstAppeareanceExecutionDone == NO) {
// Do your stuff
isfirstAppeareanceExecutionDone = YES;
}
}
@end
私があなたの質問を正しく理解している場合は、BOOL変数を設定して、viewDidAppearがすでに呼び出されていることを認識できます。例:
- (void)viewDidAppear {
if (!self.viewHasBeenSet) { // <-- BOOL default value equals NO
// Perform whatever code you'd like to perform
// the first time viewDidAppear is called
self.viewHasBeenSet = YES;
}
}
viewDidAppear
を1回だけ呼び出します。これは一度だけは呼び出されません。上記の rmaddyの回答を参照してくださいviewDidLoad
でセレクターを実行するか、viewDidAppear
でdispatch_once_t
を使用できます。より良い解決策を見つけたら、私と共有してください。これが私のやり方です。
- (void)viewDidLoad { [super viewDidLoad]; [self performSelector:@selector(myMethod) withObject:nil afterDelay:2.0]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; static dispatch_once_t once; dispatch_once(&once, ^{ //your stuff [self myMethod]; }); }
他のコメントを読むことによって(そして@rmaddyの回答に基づいて)、これはOPが要求したものではなく、質問のタイトルのためにここに来た人々のためにあることがわかります。
extension UIViewController {
var isPresentingForFirstTime: Bool {
return isBeingPresented() || isMovingToParentViewController()
}
}
[〜#〜]更新[〜#〜]
このメソッドはviewDidAppear
およびviewWillAppear
で使用する必要があります。 (@rmaddyに感謝)
更新2
このメソッドは、モーダル表示されたビューコントローラーとプッシュされたビューコントローラーでのみ機能します。 childViewControllerでは機能しません。 childViewControllersではdidMoveToParentViewController
を使用する方が良いでしょう。
状況が発生したときにBOOL値を設定してみてください。
@interface AViewController : UIViewController
@property(nonatomic) BOOL doSomeStuff;
@end
@implementation AViewController
- (void) viewWillAppear:(BOOL)animated
{
if(doSomeStuff)
{
[self doSomeStuff];
doSomeStuff = NO;
}
}
どこかでAViewControllerインスタンスを初期化します:
AddEventViewController *ad = [AddEventViewController new];
ad.doSomeStuff = YES;
ViewDidAppear
でこれを行う理由がわかりませんか?しかし、doSomeStuffがプライベートで、soSomeStuff
が1回だけ呼び出されたい場合は、通知による別の解決策を次に示します。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomeStuff) name:@"do_some_stuff" object:nil];
- (void) doSomeStuff
{}
次にどこかに投稿する:
[[NSNotificationCenter defaultCenter] postNotificationName:@"do_some_stuff" object:nil];