Cropped characters - iOS11 - Alert Dialog Ask [duplicate] - ios

This question already has an answer here:
Cropped characters - iOS11 - Alert Dialog
(1 answer)
Closed 4 years ago.
Cropped characters - iOS11 - Alert Dialog. How to fix it?
Does anyone know the reason why this is happening?
func settingsButtonPressed() {
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let closeAction = UIAlertAction(title: "Anuluj", style: .cancel) { (action) in
}
alert.addAction(closeAction)
let restorePurchases = UIAlertAction(title: "Przywróć zakupy", style: .default) { (action) in
self.restorePurchases()
}
alert.addAction(restorePurchases)
let refreshCatalogs = UIAlertAction(title: "Odśwież", style: .default) { (action) in
self.collectionView.reloadData()
}
alert.addAction(refreshCatalogs)
let delPubs = UIAlertAction(title: "Usuń publikacje", style: .destructive) { (action) in
self.deletePublications()
}
alert.addAction(delPubs)
present(alert, animated: true, completion: nil)
}

Can't reproduce. I ran your exact same code (minus the calls in the handlers, of course) and this is what I see:
My suggestion would be: try just this part of your code in a plain vanilla project, just to persuade yourself that this should work. Then start thinking about how your real app is different. Perhaps you are messing with fonts or appearance in a way that causes this issue.

Related

How to change UIAlertAction font or show UIAlertActionStyle.cancel style ActionButton on second position?

I don't want to change UILabel.appearance as it will apply to all labels.
How I can show UIAlertController that will look like below image?
Need to show bold button in the second position.
By default, when I am setting UIAlertActionStyle.cancel it shows it on the Confirm button in the first position.
It looks like this now:
I did some research but I didn't find any solution.
Swift 4.2/Swift 5
You need to set preferred action method,
//Create alertController
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
//Create and add the Confirm action
let confirmAction = UIAlertAction(title: "Confirm", style: .default, handler: { (action) -> Void in
//Do Something here...
})
alert.addAction(confirmAction)
//Create and add the Cancel action
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in
//Do Something here...
})
alert.addAction(cancelAction)
// Set Preferred Action method
alert.preferredAction = confirmAction
self.present(alert, animated: true, completion: nil)
The output will be,
You need to add them to the alertView in the right order! If you want the order to change just add the confirm button second!
alert.addAction(cancelAction)
alert.addAction(confirmAction)
Instead of:
alert.addAction(confirmAction)
alert.addAction(cancelAction)
Sure, you can. Try this
let alertView = UIAlertController(
title: "Home",
message: "Are you sure for delete Reminder",
preferredStyle: .alert)
alertView.view.tintColor = .green
let confirmAction = UIAlertAction(title: "Confirm", style: .cancel) { (_) in
// Do confirm
}
alertView.addAction(confirmAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .default) { (_) in
// Do cancel
}
alertView.addAction(cancelAction)
self.present(alertView, animated: true, completion: nil)

UIAlertController Giving error? Please Give the code for UIAlertController with Array of Strings As Buttons in Swift

This is my code:
Please Check whether anything went Wrong? Please give me the code for UIActionsheet (UIAlertController) with array in swift
let alertA = UIAlertController(title: "PlayLists", message: "Select From PlayLists Below", preferredStyle: .ActionSheet)
let action = UIAlertAction(title: "Cancel", style: .Default, handler: {(alert: UIAlertAction!) in
})
let playListModel = PlayListModel.sharedInstance
plLists = playListModel.getPlayListNames()
for(var i = 0; i < plLists.count; i++){
alertA.addAction(UIAlertAction(title: plLists.objectAtIndex(i) as? String, style: .Default, handler: {
action in
NSLog("%#",String(i))
}))
}
alertA.addAction(action)
self.presentViewController(alertA, animated: true, completion: nil)
In this code if I have 3 playlists the actionsheet shows three playlists along with cancel button. When I click the first button it will print value 4(where i stopped incrementing). Why is it printing this? It should print i value with 1, right? What's the problem? Is the Action inside the For Loop is Correct?
First of all I going to explain you why this happen, you can see if you touch any of your buttons always the output result of the call of NSLog("%#",String(i)) is plLists.count - 1, this is because you're trying to set always the index of the for statement inside the closure of the actions you're adding. The variable is outside the scope of the closure.
The main problem is that always the reference retained inside the closure in your case is the last index of the array, because as you said is increased and finally when it finish is assigned the value.
Nevertheless, you can take an approach for the title property in the action, like in the following way:
func presentAction() {
let alertA = UIAlertController(title: "PlayLists", message: "Select From PlayLists Below", preferredStyle: .ActionSheet)
let action = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
let plLists = ["List1", "List2", "List3", "List4"]
for(var i = 0; i < plLists.count; i++) {
alertA.addAction(UIAlertAction(title: plLists[i], style: .Default, handler: self.handlerForAction))
}
alertA.addAction(action)
self.presentViewController(alertA, animated: true, completion: nil)
}
func handlerForAction(action: UIAlertAction) {
print(action.title!)
}
I hope this help you.
I dont know why is it happening that way, So I Found out the Answer as an Alternative:
Using for loop in different way:
for titled in plLists{
alertA.addAction(UIAlertAction(title: titled, style: .Default, handler: {
action in
NSLog(titled)
}))
}
}
getting the correct output now, thanks for patience...

Why are the options in my UIAlertController dim and how can I fix it?

This is a weird one. I'm making a UIAlertController with the following code:
let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: UIAlertControllerStyle.ActionSheet)
let action = UIAlertAction(title: "Action 1", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancelled")
})
let action2 = UIAlertAction(title: "Action 2", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancelled")
})
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancelled")
})
optionMenu.addAction(cancelAction)
optionMenu.addAction(action)
optionMenu.addAction(action2)
self.presentViewController(optionMenu, animated: true, completion: nil)
And here's what it looks like on screen. The options are dim (I believe pulling in or being affected by the rear views).
Dimmed Options
I was able to add this code to make it pure white, but the nice-ness of the separation goes away.
let subview = optionMenu.view.subviews.first! as UIView
let alertContentView = subview.subviews.first! as UIView
alertContentView.backgroundColor = UIColor.whiteColor()
alertContentView.layer.cornerRadius = 2
And it looks like this: Non-dimmed, but not quite right
Any ideas on how to not let the background affect the options in the UIAlertController?
I added this UIAlertController to a page with a white background and it looked like it should.
Thanks!
It's not a bug. Nothing is "dimmed". The alert buttons are translucent, so they are darker over a dark background. They are also reddish over a red background and bluish over a blue background; that's what translucent means. All action sheets in all apps look like this. There's no problem here. Don't worry, be happy.
This is my objective c code. Try the swift counterpart for the same :
[alert.view setBackgroundColor:[UIColor whiteColor]];
Hope it helps!

Possible to create UIAlertController using Apple's recommended UX guidelines?

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:

Show alert in AppDelegate in Swift [duplicate]

This question already has answers here:
How to show UIAlertController from Appdelegate
(6 answers)
Closed 4 years ago.
I try the next code snippet:
var alert = UIAlertController(title: "Alert", message: "Cannot connect to : \(error!.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
in my AppDelegate, but it prints me the next error in console:
Warning: Attempt to present <UIAlertController: 0x7ff6cd827a30> on <Messenger.WelcomeController: 0x7ff6cb51c940> whose view is not in the window hierarchy!
How can I fix this error?
This is what i'm using now to do that.
var alertController = UIAlertController(title: "Title", message: "Any message", preferredStyle: .ActionSheet)
var okAction = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) {
UIAlertAction in
NSLog("OK Pressed")
}
var cancelAction = UIAlertAction(title: "No", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
Swift 5:
let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertController.Style.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
// show the alert
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
As per Jorge's answer, updated for Swift 4
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
UIAlertAction in
NSLog("OK Pressed")
}
let cancelAction = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
Swift 3.0 or above, Working in all condition , like in case of tab bar, in case of presented view etc ..
let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
// show alert
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)
I had the similar problem.
I have fixed it by presenting UIAlertController in Main Queue.
Code Looks like following.
let alert = UIAlertController(title: "My Title", message: "My Message", preferredStyle: .alert)
let actionYes = UIAlertAction(title: "Yes", style: .default, handler: { action in
print("action yes handler")
})
let actionCancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { action in
print("action cancel handler")
})
alert.addAction(actionYes)
alert.addAction(actionCancel)
DispatchQueue.main.async {
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
Have you tried using UIApplication.shared.keyWindow?.rootViewController?.present(...) ?
I suppose you are calling that code snippet from the applicationDidFinishLunchingWithOptions.
I tried it as a matter of fact because I had to. The thing is: what you are trying to do is correct but the ViewController that the AppDelegate makes and presents is about to be put on screen and before that, the code snippet tries to create an alertView and put in on top of non existent View of the RootViewController.
What I would do is move it to another delegate call which is guaranteed to be called after the RootViewController is presented.
func applicationDidBecomeActive(application: UIApplication) {
//This method is called when the rootViewController is set and the view.
// And the View controller is ready to get touches or events.
var alert = UIAlertController(title: "Alert", message: "Cannot connect to :", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}
But as always know the responsibility of the AppDelegate. It is to handle the application lifecycle and application wide delegate calls and events. If putting code here makes sense, then do it. But if you will be better off putting the code on the rootViewController or other parts then think about it too.
Anyway, hope it helps. Cheers!
I would suggest NOT doing this in the AppDelegate. The App Delegate it intended to handle Delegate functions from the OS rather than implementing things like alert views.
If you are wanting to present an alert view here to be shown at the start of the app I would do this by implementing it in your first view controller.

Resources