Why doesn't code in (isMovingToParentViewController) run in viewDidLayoutSubviews()

251 views Asked by At

I have a viewController, I'm using anchors and I want to get the frame of a button. I only want the frame when the view is pushed on so I use isMovingToParentViewController. Like this:

if isMovingToParentViewController {

    let myButtonFrame = myButton.convert(myButton.bounds, to: self.view)
}

When I add it in viewWillAppear the code to get the button's frame runs but when I add the same code to viewDidLayoutSubviews it doesn't run.

Why is that?

Just to be clear in viewDidLayoutSubviews when I add a break point it does hit if isMovingToParentViewController but the code inside of it never gets hit.

When the view gets pushed on isMovingToParentViewController does get hit, when it pops isMovingToParentViewController doesn't get hit.

override func viewDidLoad() {
    super.viewDidLoad()

    // anchors are set here but the frames haven't been set yet
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if isMovingToParentViewController {

        // this code runs
        let myButtonFrame = myButton.convert(myButton.bounds, to: self.view)
    }
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if isMovingToParentViewController {

        // this code NEVER runs
        let myButtonFrame = myButton.convert(myButton.bounds, to: self.view)
    }
}
1

There are 1 answers

0
malhal On

The header documentation states that isMovingToParentViewController and the 3 other methods are only valid in appearance callbacks like viewWillAppear thus not in layout callbacks like viewDidLayoutSubviews.

/*
  These four methods can be used in a view controller's appearance callbacks to determine if it is being
  presented, dismissed, or added or removed as a child view controller. For example, a view controller can
  check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:
  method by checking the expression ([self isBeingDismissed] || [self isMovingFromParentViewController]).
*/

#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly, getter=isBeingPresented) BOOL beingPresented NS_AVAILABLE_IOS(5_0);
@property(nonatomic, readonly, getter=isBeingDismissed) BOOL beingDismissed NS_AVAILABLE_IOS(5_0);

@property(nonatomic, readonly, getter=isMovingToParentViewController) BOOL movingToParentViewController NS_AVAILABLE_IOS(5_0);
@property(nonatomic, readonly, getter=isMovingFromParentViewController) BOOL movingFromParentViewController NS_AVAILABLE_IOS(5_0);
#else
- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);

- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
#endif