How to create a drop down menu - swift

How can I create a menu like this using swift?
Example

It's alertController with actionSheet. User this method in your button action for example.
func handleAlert()
let alertController = UIAlertController(title: "Change Profile Photo", message: nil, preferredStyle: .actionSheet)
//First action
alertController.addAction(UIAlertAction(title: "Remove current photo", style: .destructive, handler: { (_) in
// Your remove photo code here
}))
alertController.addAction(UIAlertAction(title: "Import From Facebook", style: .default, handler: { (_) in
// Your import from facebook code here
}))
//Cancel action
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alertController, animated: true, completion: nil)
}

Related

variable 'alert' is written to, but never read

I have an alert-box, which returns a number of warnings that I'm having trouble, getting rid of.
let alert = UIAlertController(title: "Delete the group?", message: "The group is removed permanently", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { [weak alert] (_) in
self.dismiss(animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
// Perform the serverside action here and dismiss
}))
self.present(alert, animated: true, completion: nil)
Both addAction-lines returns a "Variable 'alert' is written to, but never read"-warning. I don't understand, since I use it in the "present"-line in the same scope.
Any ideas?
I have all my alerts in a separate class like so;
class AlertViewController {
func someAlert(with title: String?, message: String?, viewController: UIViewController) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let someAction = UIAlertAction(title: "Action Title", style: .default) { (_) in
//Perform your action here
}
alertController.addAction(someAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
viewController.present(alertController, animated: true, completion: nil)
}
}
If you use the style: .cancel it will automatically dismiss the alert. Furthermore, as a better UX, including this .cancel will allow the user to tap anywhere on the view to dismiss the alert as well.
You can call this action where needed like so;
AlertViewController.someAlert(with: "Title", message: "Message", viewController: self)
Self is the UIViewController you wish to present upon.

How to enable a Uialertview specific button in iOS after it is clicked, using Swift?

on Button clear history I want to enable other 2 buttons. I am new in iOS.
let alert = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let markAction = UIAlertAction(title: "Mark as Urgent", style: .default, handler: { (action) in
})
let resolveAction = UIAlertAction(title: "Resolvethe conversion", style: .default, handler: { (action) in
})
markAction.isEnabled = false
resolveAction.isEnabled = false
alert.addAction(markAction)
alert.addAction(UIAlertAction(title: "Clear history", style: .default, handler: { (action) in
alert.actions.map {$0.isEnabled = true}
}))
self.present(alert, animated: true, completion: nil)
}
You can enable your actions in the clear button completion handler and present again your alert because you cannot avoid the dismiss:
let alert = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let markAction = UIAlertAction(title: "Mark as Urgent", style: .default, handler: { (action) in
// TODO: Your action
})
markAction.isEnabled = false
alert.addAction(markAction)
alert.addAction(UIAlertAction(title: "Clear history", style: .default, handler: { (action) in
alert.actions.map {$0.isEnabled = true}
self.present(alert, animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)

Why doesn't my alert view controller work

let alert = UIAlertController(title: "Title", message: "message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Title", style: UIAlertActionStyle.default, handler: { action in self.alertFunc() }))
If I build this the alert view doesn't appear. What have I missed?
P.S. I know there are some similar question but to find out what they have and I have missed is hard
You have to present the alerte view on your view.
self.present(alert, animated: true, completion: nil)
You need to present it too on your current context:
self.present(alert, animated: true, completion: nil)
Add that row at the end of your alert declaration:
let alert = UIAlertController(title: "Title", message: "message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Title", style: UIAlertActionStyle.default, handler: { action in
self.alertFunc()
}))
self.present(alert, animated: true, completion: nil)

Change the color of cancel button in UIAlertController with preferredStyle: .ActionSheet

Is it possible to change the color of cancel button to red , i know we can by using Destructive style
let cancelActionButton: UIAlertAction = UIAlertAction(title: "Cancel", style: .Destructive) { action -> Void in
print("Cancel")
}
but i want the cancel button separately , like this
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
cancelAction.setValue(UIColor.red, forKey: "titleTextColor")
This is code of how to make the alert like you said:
let alert = UIAlertController(title: "Hello", message: "Hello World", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Open in Google Maps", style: . default, handler: nil))
alert.addAction(UIAlertAction(title: "Open in Google", style: . default, handler: nil))
alert.addAction(UIAlertAction(title: "Copy Address", style: . default, handler: nil))
alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
You have to use 2 kind of style.
In here, I used .destructive and .default, It will separate alert action into 2 part
Swift 4
You can change the color of the alert action button using the below code.
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
cancelAction.setValue(UIColor.red, forKey: "titleTextColor")
Hope this helps you.
Just give the style property of the button as destructive.
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: {
(alert: UIAlertAction!) -> Void in
})
Swift4.2
If you have multiple UIAlertAction, then add "Cancel" UIAlertAction in UIAlertController like that.
let alert = UIAlertController(title: "Title", message: "Your Message", preferredStyle: UIAlertController.Style.actionSheet)
alert.addAction(UIAlertAction(title: "first",style: .default, handler: { action in
//Do something....
}))
alert.addAction(UIAlertAction(title: "second", style: .default, handler: { action in
//Do something....
}))
// Add cancel UIAlertAction
let cancelAlert = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
cancelAlert.setValue(UIColor.red, forKey: "titleTextColor")
alert.addAction(cancelAction).
self.present(alert, animated: true, completion: nil)
If you want to achieve the same output for the cancel button and also don't want to change the cancel button type to destructive. I have used cancel type for the cancel button in the code. To achieve the same, You can use the following code:-
//MARK:- Function to create the action sheet
func showAlertSheet(){
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// Create Google Map button
let googleMap = UIAlertAction(title: "Open in Google Maps", style: .default) { (action:UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
print("Ok button tapped");
}
alertController.addAction(googleMap)
// Create Map button
let map = UIAlertAction(title: "Open in Maps", style: .default) { (action:UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
print("Ok button tapped");
}
alertController.addAction(map)
// Create copy Address button
let copyAddress = UIAlertAction(title: "Copy Address", style: .default) { (action:UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
print("Ok button tapped");
}
alertController.addAction(copyAddress)
// Create Cancel button
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action:UIAlertAction!) in
print("Cancel button tapped");
}
// Change Cancel title color according to your requirements
cancelAction.setValue(UIColor.red, forKey: "titleTextColor")
alertController.addAction(cancelAction)
// Present Dialog message
self.present(alertController, animated: true, completion:nil)
}
And also you have the option to change the cancel button text color. The output of the code is like this:-
Change the style from UIAlertActionStyleDefault to UIAlertActionStyleDestructive in objective C:
UIAlertAction* button = [UIAlertAction actionWithTitle:#"Button title here"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
// Handle action here....
}];
You can use alert.view.tintColor which will be applied for .cancel and .default styles

Cannot call value of non-function type UIAlertAction

I'm not sure what's wrong with this function. I'm trying to present an alert asking if the user would like to delete the selected photo.
If the function that deletes the photo returns an error, I would like to show that error to the user.
Xcode is failing on the errorController.addAction line with the message that "cannot call value of non-function type UIAlertAction"
I'm using Swift 2
#IBAction func deletePhoto(sender: AnyObject) {
let alertController = UIAlertController(title: "Delete Photo", message: "Are you sure you want to delete this photo?", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: .Default) { UIAlertAction in
self.photoGateway!.delete(self.photo!.id!, completion: { (withError: Bool) -> Void in
if (withError == true) {
let errorController = UIAlertController(title: "Delete Failed", message: "blah", preferredStyle: UIAlertControllerStyle.Alert)
// The next line is causing the error
errorController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(errorController, animated: true, completion: nil)
} else {
self.dismissViewControllerAnimated(true, completion: nil)
}
})
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { UIAlertAction in
print("Cancelled")
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
If I take out the offending line then all works well, just the user has no way of dismissing the alert
Fixed it. Changed:
errorController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
to:
errorController.addAction(UIKit.UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
The reason this is happening is because the parameter for your callbacks is called UIAlertAction (lines 3 and 20 above) and this is overriding the declaration in UIKit. This is likely a mistake of code-completion. Just rename it to action or something like that or just _ as you don't reference it.