How to do some stuff in viewDidAppear only once?

Allen picture Allen · Jan 29, 2015 · Viewed 11.2k times · Source

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.

Answer

rmaddy picture rmaddy · Jan 29, 2015

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.