I have clicked login button and the message throw in notification center and a country picker opened and when I click on button in country picker log in view Controller must be opened but it throws an error:
memory read failed for 0x0 ........
this error comes in between obtaining controller object and present.
what should I do now??
I am using Xcode 10.1 and Swift 4
#objc func showSpinningWheel(_ notification: NSNotification) {
if whichbuttonclick == true
{
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.present(vc, animated: true, completion: nil)
}
else
{
self.performSegue(withIdentifier: "Register", sender: self)
}
}
I expect it to jump over login controller but it throws error.
This is how i add Notification Observer :
NotificationCenter.default.addObserver(
self,
selector: #selector(self.showSpinningWheel(:)),
name: Notification.Name(rawValue: "opencontrollermessagenotification"),
object: nil
)
#objc func showSpinningWheel( notification: NSNotification)
{
if whichbuttonclick == true {
self.performSegue(withIdentifier: "Login", sender: self)
} else {
self.performSegue(withIdentifier: "Register", sender: self)
}
}
and This is how i Post it :
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "opencontrollermessagenotification"), object: nil, userInfo: nil)
I want to load an alert when internet connection is not available. The function for checking internet connection is ready but I cannot load the alert. So I just put the alert code in viewDidLoad without any conditions etc. and got this error:
Warning: Attempt to present UIAlertController: 0x12752d400 on x.ViewController: 0x127646f00 whose view is not in the window hierarchy!
Code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Delegates
verificationCode.delegate = self
let alert = UIAlertController(title: "Oops!", message:"This feature isn't available right now", preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default) { _ in }
alert.addAction(action)
self.presentViewController(alert, animated: true) {}
if (!Util.isConnectedToNetwork()) {
self.isConnected = false
}
}
Could you tell me how to fix it?
The error tells you what has gone wrong.
You are trying to present a view controller in viewDidLoad except the view, although loaded, is not in any hierarchy. Try putting the code in the viewDidAppear method, which is called after the view appears on screen, and is in a view hierarchy.
Swift 4 Update
I think this could help you for your problem :
override func viewDidLoad() {
super.viewDidLoad()
verificationCode.delegate = self
let alert = UIAlertController(title: "Oops!", message:"This feature isn't available right now", preferredStyle: .alert)
let delete = UIAlertAction(title: "OK", style: .default) { (_) in }
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alert.addAction(cancelAction)
alert.addAction(delete)
alert.popoverPresentationController?.sourceView = sender as UIView
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
if (!Util.isConnectedToNetwork()) {
self.isConnected = false
}
}
Move the code to viewDidAppear from viewDidLoad
override func viewDidAppear(animated: Bool) {
// Delegates
verificationCode.delegate = self
let alert = UIAlertController(title: "Oops!", message:"This feature isn't available right now", preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default) { _ in }
alert.addAction(action)
self.presentViewController(alert, animated: true) {}
if (!Util.isConnectedToNetwork()) {
self.isConnected = false
}
}
I'm working in these lines trying to show an "Error" message if the user forgot to fill the username label or choose an option from the PickerView ("-- Choose an option please --"), but, when I run this, it takes also the other options from the picker view as an error.
If the user choose A,B,C,D it's okay. I just want to define the first one ("-- Choose an option please --") as an error, but it doesn't works.
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
let userRole:[String] = ["-- Choose an option please --", "A", "B", "C", "D"]
var selectedOption:String?
#IBOutlet weak var usernameLabel: UITextField!
#IBOutlet weak var pickerRoleLabel: UIPickerView!
#IBAction func continueButton(sender: AnyObject) {
if usernameLabel.text == "" || userRole[0] == "-- Choose an option please --" {
let alert = UIAlertController(title: "Error in form", message: "Please fill the information", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Okay", style: .Default, handler: { (action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
}
How can I improve this?
Thanks in advance!
You could always ensure your "-- Choose an option please --" string as first item. So you can just test if the value of the desired component with UIPickerView´s selectedRowInComponent method is bigger than "0".
If "0" is returned from this method, means your first position is selected, but if you receive "-1", no value was selected in your picker. Any value bigger than "0" you can considerate as a valid value.
selectedRowInComponent(_ component: Int)
#IBAction func continueButton(sender: AnyObject) {
//If you
if usernameLabel.text == "" || myPickerView.selectedRowInComponent(0) < 1 {
let alert = UIAlertController(title: "Error in form", message: "Please fill the information", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Okay", style: .Default, handler: { (action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
}
I want the user to type up the text in the pop up dialog, but I want the program to wait until the user finished writing the text in the pop up dialog
Use UIAlertController:
let alertController = UIAlertController(title: "title", message: nil, preferredStyle: .Alert)
alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in }
alertController.addAction(UIAlertAction(title: "cancel", style: UIAlertActionStyle.Cancel, handler: nil))
logInAlertController.addAction(UIAlertAction(title: "go", style: UIAlertActionStyle.Default, handler: { (action) -> Void in }
Swift 4
It sounds like you are doing your completion handling when presenting the controller instead of when the user selects an alert action.
You'll want to try something like this:
import UIKit
class MyViewController: UIViewController
{
var someStringVariable:String = ""
func presentAnAlert()
{
let alert = UIAlertController(
title: "Title",
message: "Message",
preferredStyle: .actionSheet //choose which style you prefer
)
alert.addTextField()
{ (textField) in
//this is for configuring the text field the user will see
textField.borderStyle = UITextField.BorderStyle.bezel
}
alert.addAction(UIAlertAction(title: "OK", style: .default)
{ action in
//use this space to transfer any data
let textField = alert.textFields![0]
self.someStringVariable = textField.text ?? ""
})
self.present(alert, animated: true)
{
//this will run once the action of **presenting** the view
//is complete, rather than when the presented view has been
//dismissed
}
}
override viewDidLoad()
{
super.viewDidLoad()
self.presentAnAlert()
print(self.someStringVariable)
//prints whatever the user input before pressing the OK button
}
}
I hope that helped!
I have an alert view in Xcode written in Swift and I'd like to determine which button the user selected (it is a confirmation dialog) to do nothing or to execute something.
Currently I have:
#IBAction func pushedRefresh(sender: AnyObject) {
var refreshAlert = UIAlertView()
refreshAlert.title = "Refresh?"
refreshAlert.message = "All data will be lost."
refreshAlert.addButtonWithTitle("Cancel")
refreshAlert.addButtonWithTitle("OK")
refreshAlert.show()
}
I'm probably using the buttons wrong, please do correct me since this is all new for me.
If you are using iOS8, you should be using UIAlertController — UIAlertView is deprecated.
Here is an example of how to use it:
var refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.Alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action: UIAlertAction!) in
print("Handle Ok logic here")
}))
refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
print("Handle Cancel Logic here")
}))
presentViewController(refreshAlert, animated: true, completion: nil)
As you can see the block handlers for the UIAlertAction handle the button presses. A great tutorial is here (although this tutorial is not written using swift):
http://hayageek.com/uialertcontroller-example-ios/
Swift 3 update:
let refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
print("Handle Ok logic here")
}))
refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
print("Handle Cancel Logic here")
}))
present(refreshAlert, animated: true, completion: nil)
Swift 5 update:
let refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
print("Handle Ok logic here")
}))
refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
print("Handle Cancel Logic here")
}))
present(refreshAlert, animated: true, completion: nil)
Swift 5.3 update:
let refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertController.Style.alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
print("Handle Ok logic here")
}))
refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
print("Handle Cancel Logic here")
}))
present(refreshAlert, animated: true, completion: nil)
var refreshAlert = UIAlertController(title: "Log Out", message: "Are You Sure to Log Out ? ", preferredStyle: UIAlertControllerStyle.Alert)
refreshAlert.addAction(UIAlertAction(title: "Confirm", style: .Default, handler: { (action: UIAlertAction!) in
self.navigationController?.popToRootViewControllerAnimated(true)
}))
refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action: UIAlertAction!) in
refreshAlert .dismissViewControllerAnimated(true, completion: nil)
}))
presentViewController(refreshAlert, animated: true, completion: nil)
You can easily do this by using UIAlertController
let alertController = UIAlertController(
title: "Your title", message: "Your message", preferredStyle: .alert)
let defaultAction = UIAlertAction(
title: "Close Alert", style: .default, handler: nil)
//you can add custom actions as well
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
.
Reference: iOS Show Alert
Updated for swift 3:
// function defination:
#IBAction func showAlertDialog(_ sender: UIButton) {
// Declare Alert
let dialogMessage = UIAlertController(title: "Confirm", message: "Are you sure you want to Logout?", preferredStyle: .alert)
// Create OK button with action handler
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
print("Ok button click...")
self.logoutFun()
})
// Create Cancel button with action handlder
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
print("Cancel button click...")
}
//Add OK and Cancel button to dialog message
dialogMessage.addAction(ok)
dialogMessage.addAction(cancel)
// Present dialog message to user
self.present(dialogMessage, animated: true, completion: nil)
}
// logoutFun() function definaiton :
func logoutFun()
{
print("Logout Successfully...!")
}
Hit Upvote :)
Step # 1: Make a new Separate Class
import Foundation
import UIKit
class AppAlert: NSObject {
//Singleton class
static let shared = AppAlert()
//MARK: - Delegate
var onTapAction : ((Int)->Void)?
//Simple Alert view
public func simpleAlert(view: UIViewController, title: String?, message: String?){
ToastManager.show(title: title ?? "", state: .error)
}
//Alert view with Single Button
public func simpleAlert(view: UIViewController, title: String, message: String, buttonTitle: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
//okButton Action
let okButton = UIAlertAction(title: buttonTitle, style: UIAlertAction.Style.default) {
(result : UIAlertAction) -> Void in
self.onTapAction?(0)
}
alert.addAction(okButton)
view.present(alert, animated: true, completion: nil)
}
//Alert view with Two Buttons
public func simpleAlert(view: UIViewController, title: String, message: String, buttonOneTitle: String, buttonTwoTitle: String){
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
//Button One Action
let buttonOne = UIAlertAction(title: buttonOneTitle, style: UIAlertAction.Style.default) {
(result : UIAlertAction) -> Void in
self.onTapAction?(0)
}
//Button Two Action
let buttonTwo = UIAlertAction(title: buttonTwoTitle, style: UIAlertAction.Style.default) {
(result : UIAlertAction) -> Void in
self.onTapAction?(1)
}
alert.addAction(buttonOne)
alert.addAction(buttonTwo)
view.present(alert, animated: true, completion: nil)
}
}
Step # 2: Call As
AppAlert.shared.simpleAlert(view: self, title: "Register First", message: "Please Register to Proceed", buttonOneTitle: "Cancel", buttonTwoTitle: "OK")
AppAlert.shared.onTapAction = { [weak self] tag in
guard let self = self else {
return
}
if tag == 0 {
// DO YOUR WORK
} else if tag == 1 {
// DO YOUR WORK
}
}
You may want to consider using SCLAlertView, alternative for UIAlertView or UIAlertController.
UIAlertController only works on iOS 8.x or above, SCLAlertView is a good option to support older version.
github to see the details
example:
let alertView = SCLAlertView()
alertView.addButton("First Button", target:self, selector:Selector("firstButton"))
alertView.addButton("Second Button") {
print("Second button tapped")
}
alertView.showSuccess("Button View", subTitle: "This alert view has buttons")
small update for swift 5:
let refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertController.Style.alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
print("Handle Ok logic here")
}))
refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
print("Handle Cancel Logic here")
}))
self.present(refreshAlert, animated: true, completion: nil)