How to blur the viewcontroller when alertcontroller is present?

Is it possible to do this ?? I have a UIAlertController which appears in a viewcontroller.What I wish to acheive is to blur/cover the background when the alert is present and once the alert is gone the background should be visible

import UIKit import LocalAuthentication class TabBarViewController: UITabBarController {

@IBOutlet weak var noteTabBar: UITabBar!

override func viewDidLoad() {
super.viewDidLoad()
    self.authenticateUser()
    self.tabBar.hidden = false
    self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())

    let userDefaults = NSUserDefaults.standardUserDefaults()
    userDefaults.setObject(false, forKey: "sendModeToggle")
    userDefaults.setObject("Avenir-Medium", forKey: "font")
     userDefaults.setObject(13, forKey:"fontSize")
            // Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

// MARK: Touch ID Authentication

func authenticateUser()
{
    let context = LAContext()
    var error: NSError?
    let reasonString = "Authentication is needed to access your app! :)"

    let blurEffect = UIBlurEffect(style: .Light)
    let blurVisualEffectView = UIVisualEffectView(effect: blurEffect)
    blurVisualEffectView.frame = view.bounds

    if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)
    {

        context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success, policyError) -> Void in

            if success
            {
                print("Authentication successful! :) ")
                blurVisualEffectView.removeFromSuperview()

            }
            else
            {
                switch policyError!.code
                {
                case LAError.SystemCancel.rawValue:
                    print("Authentication was cancelled by the system.")
                /*case LAError.UserCancel.rawValue:
                    print("Authentication was cancelled by the user.")
                 */   
                case LAError.UserFallback.rawValue:
                    print("User selected to enter password.")
                    NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                        self.showPasswordAlert()
                    })
                default:
                    print("Authentication failed! :(")
                    NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                        self.showPasswordAlert()
                    })
                }
            }

        })
    }
    else
    {
        print(error?.localizedDescription)
        NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
            self.showPasswordAlert()
        })
    }


}

// MARK: Password Alert

func showPasswordAlert()
{

    let blurEffect = UIBlurEffect(style: .Light)
    let blurVisualEffectView = UIVisualEffectView(effect: blurEffect)
    blurVisualEffectView.frame = view.bounds


    let alertController = UIAlertController(title: "Touch ID Password", message: "Please enter your password.", preferredStyle: .Alert)

    let defaultAction = UIAlertAction(title: "OK", style: .Cancel) { (action) -> Void in

        if let textField = alertController.textFields?.first as UITextField?
        {
            if textField.text == "notes"
            {
                print("Authentication successful! :) ")
                blurVisualEffectView.removeFromSuperview()
            }
            else
            {
                self.showPasswordAlert()

            }
        }
    }
    alertController.addAction(defaultAction)

    alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in

        textField.placeholder = "Password"
        textField.secureTextEntry = true
    }
    self.view.addSubview(blurVisualEffectView)
    self.presentViewController(alertController, animated: true, completion: nil)
}

}

Upvotes: 3

Views: 8309

Answers (5)

Jayce
Jayce

Reputation: 427

In swift 3.1

    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame = view.bounds
    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    self.view.addSubview(blurEffectView)

    let previewController = UIAlertController(title: "Following", message: "Hello", preferredStyle: .alert)

    let followAction = UIAlertAction(title: "Follow", style: .default, handler: { (UIAlertAction) in
        blurEffectView.removeFromSuperview()
    })

    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (UIAlertAction) in
        blurEffectView.removeFromSuperview()
    })

    previewController.addAction(cancelAction)
    previewController.addAction(followAction)

    present(previewController, animated: true, completion: nil)

Upvotes: 2

Sunil Sharma
Sunil Sharma

Reputation: 2689

To show UIAlertController background as blurred use UIVisualEffectView as:

 let blurEffect = UIBlurEffect(style: .Light)
 let blurVisualEffectView = UIVisualEffectView(effect: blurEffect)
 blurVisualEffectView.frame = view.bounds

 let alertController = UIAlertController.init(title: "Title", message: "Message", preferredStyle: .Alert)

 alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action: UIAlertAction!) in
     print("Handle Ok logic here")
     blurVisualEffectView.removeFromSuperview()
 }))

 alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
     print("Handle Cancel Logic here")
     blurVisualEffectView.removeFromSuperview()
 }))
 self.view.addSubview(blurVisualEffectView)
 self.presentViewController(alertController, animated: true, completion: nil)

Screenshots

Before showing alert view                                      When alert view is visible

enter image description here enter image description here

Upvotes: 13

lzl
lzl

Reputation: 469

Set a view as mask over your content using UIVisualEffectView, then add the alert over the top of the blurred view.

here's an example

private var _blurView: UIVisualEffectView?

then inside your class

func layoutBlurView(){
    if(self._blurView == nil){
        let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
        self._blurView = UIVisualEffectView(effect: blurEffect)
        self.view.insertSubview(self._blurView!, belowSubview: alertView)
    }
    self._blurView!.frame = self.view.bounds
}

where alertView is.... your alert view

Upvotes: 0

Santosh
Santosh

Reputation: 2914

You can add a UIVisualEffectView to your viewController's view property when alert is present and remove this blurView when alert is dismissed.

var blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
var blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // for supporting device rotation
view.addSubview(blurEffectView)

And when your alert is dismissed, just call blurEffectView.removeFromSuperView()

Upvotes: 2

Fogmeister
Fogmeister

Reputation: 77641

You could do this by creating a modal view controller that has a transparent background and a UIVisualEffectView on it. Have it present itself over the context of the current view controller and then have it present the alert.

That way the current view will be blurred by the view controller before it then presents the alert.

Upvotes: 0

Related Questions