Uialertview or UIalertcontroller to Display Only Once in Swift

UiAlertView or UiAlertController to display only once in Swift

Declare a global Bool variable just under import commands:

var justOnce:Bool = true

You should use it this way:

override func viewDidLoad() {
super.viewDidLoad()
var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()

if let nameIsNotNill = defaults.objectForKey("name") as? String {
name.text = defaults.objectForKey("name") as String
}

if let phoneIsNotNill = defaults.objectForKey("phone") as? String {
phone.text = defaults.objectForKey("phone") as String
}

if justOnce {
var alert = UIAlertController(title: "Disclaimer", message: "WE STRIVES TO PROVIDE ACCURATE, UP-TO-DATE INFORMATION ON THIS APPS.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Agree", style: UIAlertActionStyle.Default, handler: nil))
alert.addAction(UIAlertAction(title: "Disagree", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)

justOnce = false
}
}

How To Make an Alert Only Appear Once

Just create a global variable that is a Bool. If the app is opened it starts at false. Then once the disclaimer is seen it sets the variable to true. Then present the View Controller based on the value of the variable.

    var disclaimerHasBeenDisplayed = false

class ViewController {

override func viewDidAppear(animated: Bool) {

if disclaimerHasBeenDisplayed == false {

disclaimerHasBeenDisplayed = true

let alertController = UIAlertController(title: "Disclaimer", message: "WARNING: Wakeboarding is fun, however it can be highly dangerous.
Wake Dice is not liable for any injuries obtained while wakeboarding. Please ride carefully!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Accept", style: UIAlertActionStyle.Default,handler: nil))

self.presentViewController(alertController, animated: true, completion: nil)
}
}
}

How to set up UIAlert to display a lot of information?

To show an alert on a view controller, the following code can be used.

let a = UIAlertController(title: "Your title", message: "Your message", preferredStyle: .alert)
a.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
// Pressed "OK"
}))
self.present(a, animated: true, completion: { finished in
// Alert shown
})

However there is a limit to how much information can be fit inside an alert. If you have something longer, creating a new view controller and modally presenting it could also work. This would let you customize how you wanted information to be presented (e.g. with a scroll / page view). You can also customize your view controller to make it look like an alert, so that the purpose of it is clearer. To present a view controller modally, you can use the present method.

self.present(otherViewController, animated: true, completion: nil)

One method I have used in the path to make an alert-like modal view controller is presenting a smaller view controller over the current one, and changing it's modal presentation style so that you can see the base view controller through it.

let otherVC = self.storyboard?.instantiateViewController(withIdentifier: "OtherViewController") as! OtherViewController
otherVC.modalPresentationStyle = .overCurrentContext
otherVC.view.center = vc.view.center
otherVC.delegate = self //Create a delegate so that you can control actions such as "OK" buttons
self.view.isUserInteractionEnabled = false //Stop the user interacting with the view controller behind the alert
self.present(otherVC, animated: true, completion: nil)

Edit:
You can make the delegate control actions such as closing the alert with actions. For example, this could be an example of your delegate:

protocol AlertDelegate {
func didCancel()
func didOkay()
}

Then, you could implement this like so:

class RootViewController: UIViewController, AlertDelegate {
func didCancel() { ... }
func didOkay() { ... }

func showAlert() {
...
otherVC.delegate = self
...
}
}

Then in your Alert View Controller, you can interact with the delegate.

class MyAlert: UIViewController {
var delegate: AlertDelegate!

@IBAction func cancelButton(sender: UIButton) {
delegate.didCancel()
self.dismiss(animated: true, completion: nil)
}
}

So, when the cancel button is clicked on the alert view controller, the delegate would say it cancelled, and the modal view controller would be dismissed. Then, the root view controller would receive this action, and could handle it accordingly.

How to present UIAlertController when not in a view controller?

I posted a similar question a couple months ago and think I've finally solved the problem. Follow the link at the bottom of my post if you just want to see the code.

The solution is to use an additional UIWindow.

When you want to display your UIAlertController:

  1. Make your window the key and visible window (window.makeKeyAndVisible())
  2. Just use a plain UIViewController instance as the rootViewController of the new window. (window.rootViewController = UIViewController())
  3. Present your UIAlertController on your window's rootViewController

A couple things to note:

  • Your UIWindow must be strongly referenced. If it's not strongly referenced it will never appear (because it is released). I recommend using a property, but I've also had success with an associated object.
  • To ensure that the window appears above everything else (including system UIAlertControllers), I set the windowLevel. (window.windowLevel = UIWindowLevelAlert + 1)

Lastly, I have a completed implementation if you just want to look at that.

https://github.com/dbettermann/DBAlertController

Multiple UIAlertControllers to show one after the other in Swift

OK, I've figured it out, what I've done is get the code to be ran when I press OK on the view , so that it checks the other sections then pops another one if need be.

I've putted it in after

action -> Void in

thanks a lot

Present UIAlertController on top of everything regardless of the view hierarchy

Update Dec 16, 2019:

Just present the view controller/alert from the current top-most view controller. That will work :)

if #available(iOS 13.0, *) {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
topController.present(self, animated: true, completion: nil)
}

Update July 23, 2019:

IMPORTANT

Apparently the method below this technique stopped working in iOS 13.0 :(

I'll update once I find the time to investigate...

Old technique:

Here's a Swift (5) extension for it:

public extension UIAlertController {
func show() {
let win = UIWindow(frame: UIScreen.main.bounds)
let vc = UIViewController()
vc.view.backgroundColor = .clear
win.rootViewController = vc
win.windowLevel = UIWindow.Level.alert + 1 // Swift 3-4: UIWindowLevelAlert + 1
win.makeKeyAndVisible()
vc.present(self, animated: true, completion: nil)
}
}

Just setup your UIAlertController, and then call:

alert.show()

No more bound by the View Controllers hierarchy!

How would I create a UIAlertView in Swift?

From the UIAlertView class:

// UIAlertView is deprecated. Use UIAlertController with a
preferredStyle of UIAlertControllerStyleAlert instead

On iOS 8, you can do this:

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)

Now UIAlertController is a single class for creating and interacting with what we knew as UIAlertViews and UIActionSheets on iOS 8.

Edit: To handle actions:

alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in
switch action.style{
case .Default:
print("default")

case .Cancel:
print("cancel")

case .Destructive:
print("destructive")
}
}}))

Edit for Swift 3:

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)

Edit for Swift 4.x:

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
switch action.style{
case .default:
print("default")

case .cancel:
print("cancel")

case .destructive:
print("destructive")

}
}))
self.present(alert, animated: true, completion: nil)

IOS:Show alert only once if UISlider changes its value

1) Look at the dispatch_once API. Check out this link.

2) and 3) Save the value of the slider right before you throw the alert up in an instance variable. Set your class to be the delegate of the UIAlertView. If the cancel button is hit, set the slider back to the saved value. If the OK button is hit (which you must specify when creating the alert), do nothing.

For a UIKit primer, see Ray Wenderlich's site.



Related Topics



Leave a reply



Submit