Error/warning when using alert with text field - swift

I get the following warning/error when I create an alert with text field. When I remove the textfield, the message disappears.
Changing the translatesAutoresizingMaskIntoConstraints property of a UICollectionViewCell that is managed by a UICollectionView is not supported, and will result in incorrect self-sizing. View: <_UIAlertControllerTextFieldViewCollectionCell: 0x1529254e0; frame = (0 0; 270 24); gestureRecognizers = <NSArray: 0x600000d56be0>; layer = <CALayer: 0x6000003b5a80>>
I don't have a collection view and also I haven't changed or set to false the translatesAutoresizingMaskIntoConstraints property of a cell, that's why I don't understand the message.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(createAlert))
}
#objc private func createAlert() {
let alert = UIAlertController(title: "Alert Title", message: nil, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
let okAction = UIAlertAction(title: "OK", style: .default) { _ in
print("Action") }
alert.addAction(okAction)
alert.addAction(cancelAction)
alert.addTextField { textField in
}
present(alert, animated: true)
}
How can I solve this? Unfortunately, I have not found a solution in my research. The warning occurs not only on the simulator, but also on physical devices (iPhone X).

Related

UIAlertController freezes in Swift 5 when using addTextField (target iOS12.4) - Transitioning from Objective C

My Swift view controller is called from my mainly Objective C app. Calling function 'showAlert()' displays, but freezes the emulator. I get no error, but none of the buttons work and the textfield doesn't raise the keyboard (the placeholder shows up). (My actual code has more alertActions, which work fine if I comment out the TextField code). I even copied verbatim code from StackOverflow to display a basic alert controller with a TextField, and it has the same issue as written below.
#objc class MyVC :UIViewController {
#objc func showAlert() {
let alertController = UIAlertController(title: "Title", message: "", preferredStyle: .alert)
alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter name"
}
let saveAction = UIAlertAction(title: "Confirm", style: .default, handler: { alert -> Void in
if let textField = alertController.textFields?[0] {
if textField.text!.count > 0 {
print("Text :: \(textField.text ?? "")")
}
}
})
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
(action : UIAlertAction!) -> Void in })
alertController.addAction(cancelAction)
alertController.addAction(saveAction)
alertController.preferredAction = saveAction
self.present(alertController, animated: true, completion: nil)
}
}
A breakpoint at 'present(...' show the alert controller allocated, but stepping in from here ends with the frozen display of the alertcontroller. Any debug suggestions greatly appreciated.

Swift4 - Multiple Alerts with Text Field - Completion Handler

i am working at my startscreen (viewDidAppear). At the beginning of the app, there should be an alert with some notice message. This works fine. After you click "ok" at the notice, the next alert should pop up with a text field. In this text field you have to type in a double value. I need this double value to set up a lot of things inside the app, so I need this value outside the function to calculate with it.
E.g. The notice message describes how the app works. You click OK. Now the next alert pop up with the text field. For example it asks your height. After you type in your height and click OK the height-value is the main part of different calculations.
The problem is now, that my app works with the nil-value before I typed in the double value (e.g. height)
These are the snippets from the code.
var iNeedTheDataHere:String?
///Alerts
//Start
let startController = UIAlertController(title: "Notice", message: "notice message ", preferredStyle: .alert)
let inputController = UIAlertController(title: "Set input", message: "Please set the input", preferredStyle: .alert)
//BeforeScreenLoad
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Start Alert
startController.addAction(UIAlertAction(title: "OK", style: .default, handler:{(action:UIAlertAction!) in
self.input()
}))
self.present(startController, animated: true)
}
func input() {
inputController.addTextField()
let submitAction = UIAlertAction(title: "Submit", style: .default) { [unowned ac] _ in
let answer = inputController.textFields![0].text
iNeedTheDataHere = answer
}
inputController.addAction(submitAction)
}
When I set Breakpoints, I see that the value of the inputController is set to nil, before I typed in anything. I guess my mistake has something to do with the handler
Sorry for my English
Hope somebody can help me
let alert = UIAlertController(title: "Alert!!!", message: "Please enter your message ", preferredStyle: .alert)
alert.addTextField(configurationHandler: self.configurationTextField)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{ (UIAlertAction) in
self.number.text?=""
MBProgressHUD.hide(for: self.view, animated: true)
}))
alert.addAction(UIAlertAction(title: "Done", style: .default, handler:{ (UIAlertAction) in
}))
self.present(alert, animated: true, completion: {
})
I have made some changes in your code to achieve that:
class ViewController: UIViewController {
let startController = UIAlertController(title: "Notice", message: "notice message ", preferredStyle: .alert)
let inputController = UIAlertController(title: "Set input", message: "Please set the input", preferredStyle: .alert)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
startController.addAction(UIAlertAction(title: "OK", style: .default, handler:{(action:UIAlertAction!) in
self.input()
}))
self.present(startController, animated: true)
}
func input() {
//Present another alert with textField
let confirmAction = UIAlertAction(title: "Submit", style: .default) { (_) in
guard let textFields = self.inputController.textFields,
textFields.count > 0 else {
// Could not find textfield
return
}
//get your textField
let answerTF = textFields[0]
let answer = answerTF.text
//Get values entered by user
print(answer)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
//add your textField here
inputController.addTextField { (textField) in
//Set a placeholde for textField
textField.placeholder = "Answer"
}
inputController.addAction(confirmAction)
inputController.addAction(cancelAction)
self.present(inputController, animated: true, completion: nil)
}
}
I have added comment to explain what I am doing.
And your result will be:
You can also check demo project here.

UIAlertController Crash Error [duplicate]

This question already has answers here:
UIAlertController is Crashed (iPad)
(11 answers)
Closed 4 years ago.
Here is my code
let selectRoute = UIAlertController(title: "Select a Route", message: "Please select the route you want to create your trip on", preferredStyle: .actionSheet)
let route1 = UIAlertAction(title: "Route 1", style: .default) { (action) in
self.reminder()
self.routeID = 1
self.tableView.reloadData()
}
let route2 = UIAlertAction(title: "Route 2", style: .default) { (action) in
}
selectRoute.addAction(route1)
selectRoute.addAction(route2)
if let popoverPresentationController = selectRoute.popoverPresentationController {
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = self.view.bounds
}
self.present(selectRoute, animated: true, completion: nil)
When I run this, the actionSheet just appears just over the Navigation Controller really small, anyone know a fix?
On iPad the alert will be displayed as a popover using the UIPopoverPresentationController, it requires you define an anchor point for the presentation of the popover using either a sourceView and sourceRect or a barButtonItem.
To support iPad, include this code:
alertController.popoverPresentationController?.sourceView = self.view
alertController.popoverPresentationController?.sourceRect = self.myButton.frame
self.presentViewController(alertController, animated: true, completion: nil)
here is an example:
Suppose you have a button and you are going to show alert controller below of the button:
#IBOutlet weak var myBtn: UIButton!
let alertController = UIAlertController(title: "title :)", message:"message...", preferredStyle: .actionSheet)
let defaultAction = UIAlertAction(title: "cancel", style: .cancel, handler: nil)
let deleteAction = UIAlertAction(title: "delete", style: .destructive) { (action: UIAlertAction) in
//Do something
}
let addAction = UIAlertAction(title: "...", style: .default) { (action) in
//do something
}
alertController.addAction(addAction)
alertController.addAction(deleteAction)
alertController.addAction(defaultAction)
alertController.popoverPresentationController?.sourceRect = self.myBtn.frame
alertController.popoverPresentationController?.sourceView = self.view
self.present(alertController, animated: true, completion: nil)
If you are displaying the action sheet after the user makes a selection on a cell within a UITableView. you can use this code:
alertController.popoverPresentationController.sourceView = cell
alertController.popoverPresentationController.sourceRect = cell.bounds

UIAlertAction Background color

I have a problem with an UIAlertController, it doesn't display with a background color correctly... Can you help me?
This is the code:
let alert = UIAlertController(title: "Choose qty", message: "", preferredStyle: UIAlertControllerStyle.alert)
let pickerController = PickerQtyController()
alert.setValue(pickerController, forKey: "contentViewController")
// Testing color
alert.view.tintColor=UIColor.blue
let backView = alert.view.subviews.last?.subviews.last
backView?.layer.cornerRadius = 10.0
backView?.backgroundColor = UIColor.blue
// Btns
let saveBtn = UIAlertAction(title: "Save", style: UIAlertActionStyle.default) {
UIAlertAction in
print("UIAlertController: Saved")
pickerController.saveNewValueOfPicker()
}
let cancelBtn = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) {
UIAlertAction in
print("UIAlertController: Canceled")
}
alert.addAction(saveBtn)
alert.addAction(cancelBtn)
self.present(alert, animated: true)
Thank you!
It is ugly and wrong design. You should create a custom view controller and add your pick controller into it. Change the background to transparent and set the modal presentation style to over current context to display the custom view controller.
self.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

UIAlertController auto layout warning

I have the code which works fine for all other buttons but it is not working for one specific button. The code is:
#IBAction func Quiz(sender: AnyObject) {
NSUserDefaults.standardUserDefaults().setInteger(1, forKey: "QuizLevel")
let refreshAlert = UIAlertController(title: "Alert!", message: "Please reset.", preferredStyle: UIAlertControllerStyle.Alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
self.presentViewController(refreshAlert, animated: true, completion:nil)
}
The auto layout warning I get is:
2016-05-26 20:01:17.640 Quiz[4250:297386] <UIView: 0x7fca60571a80; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7fca6056d0c0>>'s window is not equal to <UIAlertController: 0x7fca60587620>'s view's window!
How can I correct this?
the present alert controller command would be in main thread because the change perform on the main screen that's why it shows you error.
dispatch_async(dispatch_get_main_queue(), {
let alertController = UIAlertController(title: "Hey AppCoda", message: "What do you want to do?", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
presentViewController(alertController, animated: true, completion: nil)
})