0

I have several tabs in my application (UITabBarController), and in one of them I can show modal UIViewController with blur effect (over the current controller from tab).

    let bVC = BlurViewController()
    bVC.modalPresentationStyle = .overCurrentContext
    self.present(bVC, animated: true, completion: nil)

Blurred controller is just a simple UIViewController with this code in viewDidLoad:

    let blurEffect = UIBlurEffect(style: .extraLight)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame = self.view.frame

    self.view.insertSubview(blurEffectView, at: 0)

The first problem I have here, other tabs are still accessible. User is able to tap on them without dismissing my blurred controller.

Tab items are still accessible

It's not a real problem, but when this user is back, my blurred viewcontroller has gray background. It's understandable, all areas behind it were not redrawn but it's a problem.

Gray background

The third problem: if this user would try to close my blurred controller, the first controller is just black.

I know I can fight the last two problems with this:

  1. dismiss blurred controller in viewDidDisappear.

  2. remember "the blurred state" in its parent controller.

  3. if user is back, show blurred controller again.

But maybe there is a more elegant and simple approach?

lithium
  • 1,272
  • 1
  • 14
  • 28

1 Answers1

0

Try this code: Tested in Swift 3.

First VC

   import UIKit

   class ViewController: UIViewController {

   @IBOutlet weak var imageView: UIImageView!

   override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    title = "First VC"

    //To set Background image 
    let backgroundImage = UIImage(named: "Set any image for 1st VC")
    view.backgroundColor = UIColor(patternImage: backgroundImage!)
    imageView.contentMode = .scaleToFill

    // To set BlurView
    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
    let blurView = UIVisualEffectView(effect: blurEffect)
    blurView.frame = view.frame
    imageView.addSubview(blurView)

}
  // First VC barButton 

  Note: Connect firstVc to SecondVc using segue and set identifier name to **one**

  @IBAction func toSecondVC(_ sender: AnyObject) {

    performSegue(withIdentifier: "one", sender: self)

}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if (segue.identifier == "one") {

        navigationController?.navigationBar.isHidden = false

        navigationController?.toolbar.isHidden = false

    }
   }
  }

SecondVC

 import UIKit
 class viewTwo: UIViewController {

@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    title = "Second VC"
    let backgroundImage = UIImage(named: "Set any image for 2nd VC")
    view.backgroundColor = UIColor(patternImage: backgroundImage!)
    imageView.contentMode = .scaleToFill

    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
    let blurView = UIVisualEffectView(effect: blurEffect)
    blurView.frame = view.frame
    imageView.addSubview(blurView)

}

override func viewWillAppear(_ animated: Bool) {
    self.navigationItem.setHidesBackButton(true, animated:true)
}

@IBAction func backToMainVC(_ sender: AnyObject) {

//    dismiss(animated: true, completion: nil)
    navigationController?.popViewController(animated: true)
}  

}

Output from the code:

Note: Blur looks imperfection because of ScreenCast not from the code...

enter image description here

Joe
  • 8,868
  • 8
  • 37
  • 59
  • thanks, but I'm not sure this is relevant to my problem. in your example you have two separate viewcontrollers with blurred background (and it works, obviously, because any of these will be redrawn). in my case, i have one viewcontroller _over_ another (and this viewcontroller, behind the blurred one, is not redrawn). – lithium Oct 20 '16 at 14:44
  • Now I gotcha.you should mentioned u using a UITabBarController.not 2 viewController overlapping each other. – Joe Oct 20 '16 at 17:57
  • no, this code is from example project. i'm not passing any data between these controllers (except "bVC.modalPresentationStyle = .overCurrentContext" as you can see in my code snippets). – lithium Oct 20 '16 at 17:57
  • I see.Now your problem goes even easier....you know,you can still use my answer.same logic applies... – Joe Oct 20 '16 at 18:04
  • no, my item1 has some button. when this button is tapped, uiviewcontroller (with blur view inside) will be shown. – lithium Oct 20 '16 at 18:33
  • let me make you clear. if you using tabBarController that means item1 is always in there and it always presentable.you can't do transition. you doing a wrong approach or you haven't mentioned yet.Can you update your post with MainStoryBoard hierarchy. so i can see how the storyboards connected.my time is limited? – Joe Oct 20 '16 at 18:55