I want to check the pasteboard and show an alert if it contains specific values when the view appears. I can place the code into viewDidLoad
to ensure it's only invoked once, but the problem is that the alert view shows too quickly. I know I can set a timer to defer the alert's appearance, but it's not a good work-around I think.
I checked the question iOS 7 - Difference between viewDidLoad and viewDidAppear and found that there is one step for checking whether the view exists. So I wonder if there's any api for doing this?
Update: The "only once" means the lifetime of the view controller instance.
viewWillAppear(_:) is called every time the view appears. In this simple app, that means it is only called once. However, imagine your app has several views, and you can move between them. viewWillAppear(_:) is called every time your view is displayed.
viewDidAppear is called once you see the loaded view on screen. It is called after view appeared. ViewDidAppear is called everytime when you see the view after it is loaded. if you push and then pop any other viewController on that view then again viewDidAppear gets called.
As the name suggests the viewWillAppear is called before the view is about to appear and viewDidAppear is called when view did appear.
The difference between viewDidAppear and viewDidLoad is that viewDidAppear is called every time you land on the screen while viewDidLoad is only called once which is when the app loads.
There is a standard, built-in method you can use for this.
Objective-C:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if ([self isBeingPresented] || [self isMovingToParentViewController]) { // Perform an action that will only be done once } }
Swift 3:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if self.isBeingPresented || self.isMovingToParentViewController { // Perform an action that will only be done once } }
The call to isBeingPresented
is true when a view controller is first being shown as a result of being shown modally. isMovingToParentViewController
is true when a view controller is first being pushed onto the navigation stack. One of the two will be true the first time the view controller appears.
No need to deal with BOOL
ivars or any other trick to track the first call.
rmaddy's answers is really good but it does not solve the problem when the view controller is the root view controller of a navigation controller and all other containers that do not pass these flags to its child view controller.
So such situations i find best to use a flag and consume it later on.
@interface SomeViewController() { BOOL isfirstAppeareanceExecutionDone; } @end @implementation SomeViewController -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if(isfirstAppeareanceExecutionDone == NO) { // Do your stuff isfirstAppeareanceExecutionDone = YES; } } @end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With