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.
Related
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)
}
I have an app with a TextField. If TextField is empty then it is displayed UIAlertView with one button. When a user taps on a button in UIAlertView, he must return to the TextField.
I'm using self.TextField.becomeFirstResponder() for this. It works. But the problem is that the keyboard is displayed really slowly. It looks like there is a one second delay before displayed.
if TextField.text?.isEmpty ?? true {
let alert = UIAlertController(title: "Title", message: "Text", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay", style: .cancel, handler: { (action: UIAlertAction!) in
self.TextField.becomeFirstResponder()
}))
self.present(alert, animated: true)
print("textField is empty")
} else { ...
Make sure that the Slow Animation is disabled in Debug menu:
I am not getting what's wrong with my code. I am simply displaying an alert with "Ok" button and when user click on "Ok", then alert should go. But its not getting disappeared. Using Swift3 for programming. Is viewDidAppear() right place to put this code? Or am I doing something wrong?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "Wrong Item", message: "Could not find details of an item.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true, completion: nil)
}
UPDATE:
When I put the same code in other controller, it worked.
In original controller, in viewDidLoad(), I have an Async call like below. Is this problem because of that?
DispatchQueue.global(qos: .background).async {
self.getDetails(onCompletion: {(json: JSON) in
let dict = self.convertToDictionary(text: json.stringValue)
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
//Other UI update operation
}
})
}
I also override viewWillDisappear() and viewWillAppear(), just to set Title of Screen.
are you calling UIApplication.shared.beginIgnoringInteractionEvents()
anywhere bro?? if yes that is your problem.
If we create a new "single view" project
For the the following two ways of presenting the alert we get the following behaviors
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let alertController = UIAlertController(title: "Wrong Item", message: "Could not find details of an item.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true, completion: nil)
}
In the console you will see
2017-08-15 16:27:35.871 test[66719:7754741] Warning: Attempt to present on whose view is not in the window hierarchy!
and no alert on the UI.
and for:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "Wrong Item", message: "Could not find details of an item.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true, completion: nil)
}
every thing works as expected.
So yes, view did appear is the place.
About viewDidLoad() and viewDidAppear(_:)
From the looks of it the problem lies with
beginIgnoringInteractionEvents
If you are putting your alert on viewDidAppear you should see it but if you don't see it, please note the following:
Even if you put this piece of code in viewdidload
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
//Other UI update operation
}
it may get executed later (depends on when the parsing finishes) than the call of viewDidAppear
and this is because:
DispatchQueue.global(qos: .background).async
Did you check this reason?
I add below code in viewDidAppear() just before Alert code and it started working. I kept below code at both location, i.e in Async call as well as in viewDidAppear()
self.activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
endIgnoringInteractionEvents() is in an async method when you click OK this method haven't been called. so you can't dismiss alert.
Your code looks fine, and viewDidAppear is fine as the your view controller will be loaded properly and it won't break the main thread to show you the alert. There's should be some other problem with your code, (bug of) Xcode, or derived data problem.
You can do a couple of things to see the actual problem:
Clean build
Delete file from Derived Data
Delete App from Simulator
Clean once again
Restart Xcode and Simulator
Rebuild to see if it works or not.
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.
Apple's iOS UX guidelines show the following example:
...where:
When the most likely button performs a nondestructive action, it
should be on the right in a two-button alert. The button that cancels
this action should be on the left.
When the most likely button performs a destructive action, it should
be on the left in a two-button alert. The button that cancels this
action should be on the right.
Source: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/Alerts.html
However, it does not seem possible to implement this guidance with the current iOS APIs (testing on iOS 9 with Swift). Here's one attempt. But I've tried varying the order of adding the alert actions, and changing which action is .Default vs. .Cancel style. No combination appears to work.
#IBAction func showAlertAction(sender: AnyObject)
{
let title = "An Alert that Offers Two Alternatives Is Easy for People to Use"
let alertViewController = UIAlertController(title: title, message: nil, preferredStyle: UIAlertControllerStyle.Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (alert :UIAlertAction!) -> Void in
print("'Cancel' tapped")
})
alertViewController.addAction(cancelAction)
let safeChoiceAction = UIAlertAction(title: "Safe Choice", style: UIAlertActionStyle.Default, handler: { (alert :UIAlertAction!) -> Void in
print("'Safe Choice' tapped")
})
alertViewController.addAction(safeChoiceAction)
self.presentViewController(alertViewController, animated: true, completion: nil)
}
Result: