Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hide the iOS app content view when app is not active?

Tags:

ios

swift

I'm trying to add a cover screen to app when app is pushed to background by user.

I have these two methods on AppDelegate to add/remove the cover view.

func showCover(){
  let blackV = UIView(frame: UIApplication.shared.keyWindow?.bounds ?? .zero)
  blackV.backgroundColor = .black
  blackV.tag = kCoverTag
  let imgV = UIImageView(image: UIImage(named: "Logo-White"))
  imgV.center = blackV.center
  blackV.addSubview(imgV)
  UIApplication.shared.keyWindow?.addSubview(blackV)
}

func hideCover(){
  if let blackV = UIApplication.shared.keyWindow?.subviews.filter({$0.tag == kCoverTag}).first{
     blackV.removeFromSuperview()
   }
}

The tag value is declared on AppDelegate:

 let kCoverTag = 987

In the applicationWillResignActive , I apply the cover

func applicationWillResignActive(_ application: UIApplication) {
    showCover()
}

and in didBecomeActive, I remove the cover.

func applicationDidBecomeActive(_ application: UIApplication) {
   hideCover()
}

This works fine when app is sent to background by pressing home button.

Right after the applicationDidBecomeActive is called, when I print the subviews of keyWindow , I get the output as:

po UIApplication.shared.keyWindow?.subviews
▿ Optional<Array<UIView>>
  ▿ some : 2 elements
    - 0 : <UITransitionView: 0x7f97bd82ffc0; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x6000028ecce0>>
    - 1 : <UIView: 0x7f97bae27f20; frame = (0 0; 414 896); tag = 987; layer = <CALayer: 0x600002868400>>

This is good as it shows the cover view as one of the subview added to the key window.

Now, when the app is sent to background by calling UIApplication.shared.openURL , the applicationWillResignActive is called as expected.

And when the user press the "Back to app button" , the app will be shown back to user.

Now,when I print the subviews of key window in the didBecomeActive method right before calling hideCover() method, it looks like it has only one subview.

po UIApplication.shared.keyWindow?.subviews
▿ Optional<Array<UIView>>
  ▿ some : 1 element
    - 0 : <UITransitionView: 0x7f97bfc05510; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x6000029984c0>>

Since this shows only one view, the hideCover() method couldn't find the subview and hence couldn't remove it. But in the app I could see the cover view .

I'm wondering why the keyWindow subviews didn't show the added cover view.

I'm testing this in simulator.

Update:

I did two separate print calls

Right after adding the cover view:

print("resign active",UIApplication.shared.keyWindow?.subviews)

This show two subviews for keyWindow

and right before removing the cover view in didBecomeActive method:

print("did become active",UIApplication.shared.keyWindow?.subviews)

This show only ONE subview for keyWindow

like image 337
Teja Nandamuri Avatar asked Nov 07 '25 16:11

Teja Nandamuri


1 Answers

Don't use keyWindow here. That's not the right tool. There can be other windows created by the system and may have input focus via makeKey(). Present the view from the window.rootViewController from your UIApplicationDelegate. See QA1838: Preventing Sensitive Information From Appearing In The Task Switcher for Apple's recommended way to implement what you're trying to do. Also see Preparing Your UI to Run in the Background for additional guidance.

like image 104
Rob Napier Avatar answered Nov 09 '25 08:11

Rob Napier



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!