UIButton if statement swift - ios

I want the button to go to the QaController if the word Hello is typed otherwise I want the alert to appear and then go back to the home screen (viewController) but it doesn't seem to work
#IBAction func submitButton(sender: AnyObject) {
if TextField.text.containsString("Hello"){
let secondViewController:QaController = QaController()
self.presentViewController(secondViewController, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Thank You!", message:
"We appreciate your feedback!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
let homeViewController:ViewController = ViewController()
self.presentViewController(homeViewController, animated: true, completion: nil)
}
}
The code works fine without the IF statements so I'm not sure whats wrong :/
What goes wrong is when I click Submit, when I put "Hello" in it shows a black screen with no error message, instead of displaying the correct view
Thanks in advance!

I think you are comparing your string with lower case, May be your text field value is "hello" not equal to "Hello". So please compare like
if(TextField.text!.caseInsensitiveCompare("Hello") == NSComparisonResult.OrderedSame)
{
// do your stuff
}
else{
print(TextField.text)
}
Hope it will help you.

Related

Swift - How to stop the keyboard from dismissing when an alert shows up

I have a simple view with a text field that becomes the first responder when the view loads. If the user enters the wrong code, an 'oops' alert dialogue pops up, and the keyboard dismisses, and upon clicking an option on the alert dialogue, the keyboard appears again, resulting in my view moving about.
Is there a way to stop this keyboard - ever - dismissing? I tried to use this I found elsewhere:
override var disablesAutomaticKeyboardDismissal: Bool { return true }
however it doesn't seem to fix the problem. Could anyone give me a heads up? :) Thanks!
fixed with the following solution, modified from this answer - https://stackoverflow.com/a/47068284/14815664
func displayError(message: String) {
let controller = UIAlertController(title: "Oops!", message: message, preferredStyle: .alert)
controller.addAction(UIAlertAction(title: "Dismiss", style: .default))
guard let alertWindow = UIApplication.shared.windows.last,
alertWindow.windowLevel == UIWindow.Level(rawValue: 10000001.0) else {
navigationController.present(controller, animated: true, completion: nil)
return
}
alertWindow.rootViewController?.present(controller, animated: true, completion: nil)
}

iOS - UIAlertController actions not triggering handler

I'm extremely new to iOS. I'm trying to show a dialog to the user to get some input, but the actions are never triggered. I've been searching on the net for hours and no answer seem to work for me.
Here's the function I'm trying to use to show the dialog:
private func showAmountDialog(type: String, onComplete: #escaping (Double) -> Void) {
let alert = UIAlertController(title: "Enter an amount", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: LzStrings.Common_Cancel, style: .cancel, handler: nil))
alert.addTextField(configurationHandler: { textField in
textField.placeholder = "0.00 \(type)"
textField.keyboardType = .decimalPad
})
alert.addAction(UIAlertAction(title: LzStrings.Common_OK, style: .default) { (UIAlertAction) in
if let input = alert.textFields?.first?.text, let amount = Double(input) {
print("Your amount: \(amount)")
}
})
self.present(alert, animated: true)
}
self here is my ViewController which has a parent of UIViewController type and several other protocols.
What I might be doing wrong?
EDIT: The way I knew it isn't executing is using break-points and not by relying on print("...")
Also, since I added the TextField right before adding the action, the nullability check is useless and the textFields.first is never nil, so in both cases, a break-point should be triggered or the print("...") should be executed, which neither of them is happening.
EDIT 2: Since the if statement can do a little distraction, I edited my code this way and tested again:
alert.addAction(UIAlertAction(title: LzStrings.Common_OK, style: .default) { (UIAlertAction) in
if let input = alert.textFields?.first {
if let amount = Double(input.text ?? "") {
print("Your amount: \(amount)")
} else {
print("Can't cast this string to double")
}
} else {
print("Text field is null")
}
})
Still, no feedback from the dialog.
PS: Even the Cancel button doesn't work.
EDIT 3: My dismiss function is overridden in the super class, but it passes completion closure normally:
override open func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if let navigationController = self.navigationController as? NavigationController {
navigationController.dismiss(animated: flag, completion: completion)
} else {
super.dismiss(animated: flag, completion: completion)
}
}
After having a conversation with one of my colleagues, we found out that to show standard UIAlertController we must use this:
self.view.window!.rootViewController?.present(alert, animated: true, completion: nil)
Instead of this
self.present(alert, animated: true, completion: nil)
It fixed my issue. I hope someone will find this helpful.
Another option is to use an extention for ViewController:
extension UIViewController {
//Show a basic alert
func showAlert(alertText : String, alertMessage : String) {
let alert = UIAlertController(title: alertText, message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Got it", style: UIAlertActionStyle.default, handler: nil))
//Add more actions as you see fit
self.present(alert, animated: true, completion: nil)
}
}

<_UIPopoverBackgroundVisualEffectView> is being asked to animate its opacity

I am trying to show an (AlertController) Action sheet. But I am getting this waning in console " <_UIPopoverBackgroundVisualEffectView 0x7fd65ef76ec0> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1. "
here is my code :-
extension GroupDataView {
func callDot (sender : UIButton)
{
let alert = UIAlertController(title: nil, message: nil,
preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Edit Group", style: .default , handler:{ (action)in
print("User click Edit Group")
}))
alert.addAction(UIAlertAction(title: "Create Folder", style: .default , handler:{ (action)in
print("User click Create Folder button")
}))
alert.addAction(UIAlertAction(title: "Delete Group", style: .destructive , handler:{ (action)in
print("User click Delete Group button")
}))
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = sender
popoverController.sourceRect = sender.bounds
self.present(alert, animated: true, completion: {
print("completion block")
})
}
else
{
self.present(alert, animated: true, completion: {
print("completion block")
})
}
}
}
I don't know why this warning is showing in console.
ActionSheet is coming properly but how to remove that warning?
Thanks
iOS Bug
See answer by #Hardy on Apple Developer Forum: Warning message from UIPopover †
... seems to be a bug in iOS. But it does not seem to be critical. Though - I believe - that sometimes the area below the UIAlertController is not correctly drawn. I can see for a short period of time a black background flashing although the background of the underlying view is not black.
† Cached on Google here
I had the same problem, and I resolved it by setting animated: false in self.present or/and self.dismiss function. See the last comment in https://forums.developer.apple.com/thread/53677
I realise this is an old question but I was just faced with the same issue and I found a workaround by delaying the presentation by 0.001 seconds so when you normally call this function I used this code for the delay
[self performSelector:#selector(viewBookmark:) withObject:bookmarkBarButton afterDelay:0.001];
Please excuse the OBJ-C but a similar delay in swift should have the same result of not displaying 2 views at the same time.

Present View Controller doesn't work in Swift

I have got the below piece of code :
let title = "You are not connected to DropBox"
let message = "Please go back to the main page and try to log in again"
let okText = "OK"
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
let okayButton = UIAlertAction(title: okText, style: UIAlertActionStyle.Cancel, handler: nil)
alert.addAction(okayButton)
if dbRestClient == nil{
print("please refresh me")
presentViewController(alert, animated: true, completion: nil)
}`
However my alert doesn't show up. I am calling this alert from a View Controller that actually shows on the page so its not the case where my VC is working behind the scene. Please let me know what I am doing wrong here.
Use self.presentViewController(alert, animated: true, completion: nil) instead.
Should work after adding self.

presentViewController not working

I have this piece of code where I present the alert :
func arraysize() -> [Int]? {
let title = "Your file is empty"
let message = "Please refer to the instructions"
let okText = "OK"
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
let okayButton = UIAlertAction(title: okText, style: UIAlertActionStyle.Cancel, handler: nil)
alert.addAction(okayButton)
do{
....
if array?.isEmpty == true{
print("the array is empty")
presentViewController(alert, animated: true, completion: nil)
}
}
catch let error {
print(error)
}
return array
}
However my alert doesn't show. It used to show and although I haven't changed any code it stopped working for me. Can somebody help me understand what I am doing wrong?
P.S. I am also getting this warning :
[16632:713433] Warning: Attempt to present UIAlertController whose view is not in the window hierarchy!
Could this be it?
As #rmaddy explained in the comments, my problem was that I was trying to show an alert from the controller that never appears on the actual screen. I fixed this by calling this method from a controller that appears on the screen and it worked.

Resources