@@ -668,36 +668,55 @@ private extension CardsBaseViewController {
668668 footerView. isHidden = !hasSnapshot
669669 footerView. alpha = 1
670670 footerStackHeightConstraint. constant = Constants . Layout. footerStackHeight
671- tabContainerBottomToViewConstraint. isActive = false
672- footerBottomToViewConstraint. isActive = false
673- footerBottomToSafeConstraint. isActive = true
671+ applyFooterBottomLayout ( extendToBottom: false )
672+ applyFooterLayoutIfNeeded ( )
674673 return
675674 }
676675
677676 let shouldExtendToBottom = tab == . alerts || tab == . settings
678- tabContainerBottomToViewConstraint. isActive = shouldExtendToBottom
679- footerBottomToViewConstraint. isActive = shouldExtendToBottom
680- footerBottomToSafeConstraint. isActive = !shouldExtendToBottom
677+ applyFooterBottomLayout ( extendToBottom: shouldExtendToBottom)
681678
682679 let shouldCollapse = !hasSnapshot || tab == . alerts || tab == . settings
683680 let targetAlpha : CGFloat = shouldCollapse ? 0 : 1
684681 footerStackHeightConstraint. constant = shouldCollapse ? 0 : Constants . Layout. footerStackHeight
685682 footerView. isUserInteractionEnabled = !shouldCollapse
686683 footerView. isHidden = !hasSnapshot
687684
688- if animated {
685+ if animated && view . window != nil {
689686 UIView . animate (
690687 withDuration: Constants . Animation. tabTransitionDuration,
691688 delay: 0 ,
692689 options: [ . curveEaseInOut, . allowUserInteraction] ,
693690 animations: {
694691 self . footerView. alpha = targetAlpha
695- self . view . layoutIfNeeded ( )
692+ self . applyFooterLayoutIfNeeded ( )
696693 }
697694 )
698695 } else {
699696 footerView. alpha = targetAlpha
697+ applyFooterLayoutIfNeeded ( )
698+ }
699+ }
700+
701+ private func applyFooterBottomLayout( extendToBottom: Bool ) {
702+ // Deactivate incompatible constraints first to avoid transient invalid states.
703+ if extendToBottom {
704+ footerBottomToSafeConstraint. isActive = false
705+ tabContainerBottomToViewConstraint. isActive = true
706+ footerBottomToViewConstraint. isActive = true
707+ } else {
708+ tabContainerBottomToViewConstraint. isActive = false
709+ footerBottomToViewConstraint. isActive = false
710+ footerBottomToSafeConstraint. isActive = true
711+ }
712+ }
713+
714+ private func applyFooterLayoutIfNeeded( ) {
715+ // Avoid forcing an immediate layout pass while the VC is off-screen.
716+ if view. window != nil {
700717 view. layoutIfNeeded ( )
718+ } else {
719+ view. setNeedsLayout ( )
701720 }
702721 }
703722
0 commit comments