How to create an alert like Instagram unfollow alert(two buttons, image and message) on iOS? Is there any ready component or should I develop it from scratch?
Here is a screenshot:
There is an implementation (UIAlertController), but without the image.
Here's a working example:
UIAlertController* deleteAlert = [UIAlertController alertControllerWithTitle:#"Unfollow?"
message:
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* unfollowAction = [UIAlertAction actionWithTitle:#"Unfollow" style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action) {
//Code to unfollow
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"Cancel", nil) style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
}];
[deleteAlert addAction:unfollowAction];
[deleteAlert addAction:cancelAction];
[self presentViewController:deleteAlert animated:YES completion:nil];
You can find more informations on how to add an image to a UIAlertController in this post:
Add Image to UIAlertAction in UIAlertController
Swift 4 version
let deleteAlert = UIAlertController(title: "Unfollow", message: "", preferredStyle: UIAlertController.Style.actionSheet)
let unfollowAction = UIAlertAction(title: "Unfollow", style: .destructive) { (action: UIAlertAction) in
// Code to unfollow
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
deleteAlert.addAction(unfollowAction)
deleteAlert.addAction(cancelAction)
self.present(deleteAlert, animated: true, completion: nil)
Related
I am trying to use this code in a Pacman game I got from some website but had to change UIAlertView to UIAlertController except the following code has two errors that I don't know how to fix (I am really new to programming and feel like this is a really newbie question - sorry!!)
The first error is in line 4: No known class method for selector alertControllerWithTitle
A second error is in the last line: no visible interface declares the selector show
- (void)collisionWithExit: (UIAlertController *)alert {
if (CGRectIntersectsRect(self.pacman.frame, self.exit.frame)) {
[self.motionManager stopAccelerometerUpdates];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Congratulations"
message:#"You've won the game!"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil
preferredStyle:UIAlertControllerStyleAlert];
[alert show];
}
}
Please check the following code:
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"My Alert"
message:#"This is an alert."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
Check below this code.
for Objective-C:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:#"Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//button click event
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancel];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
for Swift 4.x:
let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
switch action.style {
case .default:
print("default")
case .cancel:
print("cancel")
case .destructive:
print("destructive")
}
}))
self.present(alert, animated: true, completion: nil)
Swift 5: Simple Extension
extension UIViewController {
func presentAlert(withTitle title: String, message : String, actions : [String: UIAlertAction.Style], completionHandler: ((UIAlertAction) -> ())? = nil) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for action in actions {
let action = UIAlertAction(title: action.key, style: action.value) { action in
if completionHandler != nil {
completionHandler!(action)
}
}
alertController.addAction(action)
}
self.present(alertController, animated: true, completion: nil)
}
}
Usage:
self.presentAlert(withTitle: "Network Error", message: "Please check your internet connection", actions: [
"Retry" : .default, "Cancel": .destructive] , completionHandler: {(action) in
if action.title == "Retry" {
print("tapped on Retry")
}else if action.title == "Cancel" {
print("tapped on Cancel")
}
})
OR
self.presentAlert(withTitle: "Mail services are not available", message: "Please Configure Mail On This Device", actions: ["OK" : .default] , completionHandler: nil)
I have two button but I just wanna change one to red.When I use the function below
it change all to red. I just want to change color of only one button. How can i do it?
alertController.view.tintColor = UIColor.redColor()
let alertController = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
alertController.setValue(NSAttributedString(string: title, attributes: [NSFontAttributeName : UIFont.appFont_OpenSans_Regular(fontSize: 15),NSForegroundColorAttributeName : BLACK_COLOR]), forKey: "attributedTitle")
alertController.setValue(NSAttributedString(string: message, attributes: [NSFontAttributeName : UIFont.appFont_OpenSans_Regular(fontSize: 13),NSForegroundColorAttributeName : APP_COLOR_BLUE_1]), forKey: "attributedMessage")
You can try this,
deleteAction.setValue(color, forKey: titleTextColor)
It works for me!
Swift
you need to use UIAlertActionStyle.Destructive for button text color in red
let alert = UIAlertController(
title: "Basic alert style",
message: "Basic alert With buttons",
preferredStyle: .alert )
let Reset = UIAlertAction(
title: "Reset",
style: .destructive) { (action) in
// do your stuff
}
let Cancel = UIAlertAction(
title: "Cancel", style: .default) { (action) in
// do your stuff
}
alert.addAction(Reset)
alert.addAction(Cancel)
present(alert, animated: true, completion: nil)
Objective-C
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:#"Basic Alert style"
message:#"Basic Alert With Buttons"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *Reset = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Reset", #"Reset action")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action)
{
NSLog(#"Reset action");
}];
UIAlertAction *Cancel = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(#"Cancel action");
}];
[alert addAction:Reset];
[alert addAction:Cancel];
[self presentViewController:alert animated:YES completion:nil];
output
for additional Information see this
only red Color is possible when you set UIAlertActionStyle.Destructive
Check this link
UIAlertController custom font, size, color
I want to realize a function about changing password. It requires users to input their previous password in an alert dialog.
I want to click the button "Confirm the modification" then jump to the other view controller for changing password. I have written some code, but I don't know how to write in the next moment.
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Change password" message:#"Please input your previous password" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"please input your previous password";
textField.secureTextEntry = YES;
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"cancel" style:UIAlertActionStyleCancel handlers:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"Confirm the modification" style:UIAlertActionStyleDestructive handler:*(UIAlertAction *alertAction) {
if (condition) {
statements
}
}];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
You will get all added textfields from alert controller by its textFields readonly property, you can use it to get its text.
Like
Swift 4:
let alertController = UIAlertController(title: "", message: "", preferredStyle: .alert)
alertController.addTextField { textField in
textField.placeholder = "Password"
textField.isSecureTextEntry = true
}
let confirmAction = UIAlertAction(title: "OK", style: .default) { [weak alertController] _ in
guard let alertController = alertController, let textField = alertController.textFields?.first else { return }
print("Current password \(String(describing: textField.text))")
//compare the current password and do action here
}
alertController.addAction(confirmAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
Note: textField.text is optional, unwrap it before using
Objective-C:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"" message:#"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = #"Current password";
textField.secureTextEntry = YES;
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"Current password %#", [[alertController textFields][0] text]);
//compare the current password and do action here
}];
[alertController addAction:confirmAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"Canelled");
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
By [[alertController textFields][0] text] this line, it will take first textfield added to the alerController and get its text.
You can add multiple textfields to alert controller and access them with the alert controller's textFields property
If the new password is an empty string, present the alert again. Or another way would be to disable the "Confirm" button, enabling it only when text field has text.
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"confirm the modification" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
UITextField *password = alertController.textFields.firstObject;
if (![password.text isEqualToString:#""]) {
//change password
}
else{
[self presentViewController:alertController animated:YES completion:nil];
}
}];
Here is an updated answer for Swift 4.0 that creates the desired kind of textfield:
// Create a standard UIAlertController
let alertController = UIAlertController(title: "Password Entry", message: "", preferredStyle: .alert)
// Add a textField to your controller, with a placeholder value & secure entry enabled
alertController.addTextField { textField in
textField.placeholder = "Enter password"
textField.isSecureTextEntry = true
textField.textAlignment = .center
}
// A cancel action
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
print("Canelled")
}
// This action handles your confirmation action
let confirmAction = UIAlertAction(title: "OK", style: .default) { _ in
print("Current password value: \(alertController.textFields?.first?.text ?? "None")")
}
// Add the actions, the order here does not matter
alertController.addAction(cancelAction)
alertController.addAction(confirmAction)
// Present to user
present(alertController, animated: true, completion: nil)
And how it looks when first presented:
And while accepting text:
Swift 5.1
#objc func promptAddDialog() {
let ac = UIAlertController.init(title: "Enter answer", message: nil, preferredStyle: .alert)
ac.addTextField{ textField in
textField.placeholder = "Answer"
textField.textAlignment = .center
}
let submitAction = UIAlertAction(title: "Submit", style: .default) {
[weak self, weak ac] _ in
guard let answer = ac?.textFields?[0].text else { return }
self?.submit(answer)
}
ac.addAction(submitAction)
present(ac, animated: true)
}
I was wondering if there were a built-in view in XCode for displaying pop-up menus like this for iOS apps? Something like an alert, except with just a set of vertically-stacked buttons?
EDIT:
I knew about UIAlertController, just not that its buttons stack vertically after you add more than 2, which is the style I was going for. Just to clear, for just buttons set title and message to nil as well.
Yes. It's called a UIAlertController
You can use an UIAlertController
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:#""
message:#"" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *searchAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Search for an image", #"search action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
//Add your code
}];
UIAlertAction *choosePhotoAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Choose Photo", #"choosePhoto action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
//Your code
}];
UIAlertAction *takePhotoAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Take Photo", #"takePhoto action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
//Your code
}];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"cancel action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(#"cancel action");
}];
[alertController addAction:searchAction];
[alertController addAction:choosePhotoAction];
[alertController addAction:takePhotoAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
Yes, UIAlertController is provided for setting other controls on alert view.
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"My Title"
message:#"Enter User Credentials"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Do Some action here
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Username";
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Password";
textField.secureTextEntry = YES;
}];
[self presentViewController:alert animated:YES completion:nil];
#Richa solution but in swift version
let alertController = UIAlertController(title: "", message: "", preferredStyle: .alert)
let searchAction = UIAlertAction(title: NSLocalizedString("Search for an image", comment: "search action"), style: .default, handler: {(action: UIAlertAction) -> Void in
//Add your code
})
let choosePhotoAction = UIAlertAction(title: NSLocalizedString("Choose Photo", comment: "choosePhoto action"), style: .default, handler: {(action: UIAlertAction) -> Void in
//Your code
})
let takePhotoAction = UIAlertAction(title: NSLocalizedString("Take Photo", comment: "takePhoto action"), style: .default, handler: {(action: UIAlertAction) -> Void in
//Your code
})
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: "cancel action"), style: .default, handler: {(action: UIAlertAction) -> Void in
print("cancel action")
})
alertController.addAction(searchAction)
alertController.addAction(choosePhotoAction)
alertController.addAction(takePhotoAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
I have seen a couple screen shots of a UIAlertControllers with an image on the left of the row but I do not seen it in the documentation. An example visual is
Here is the code that I have for my controller right now:
UIAlertController * view = [UIAlertController
alertControllerWithTitle:#"My Title"
message:#"Select you Choice"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
[view addAction:ok];
[self presentViewController:view animated:YES completion:nil];
And that's how it's done:
let image = UIImage(named: "myImage")
var action = UIAlertAction(title: "title", style: .default, handler: nil)
action.setValue(image, forKey: "image")
alert.addAction(action)
the image property is not exposed, so there's no guarantee of this working in future releases, but works fine as of now
UIAlertController * view= [UIAlertController
alertControllerWithTitle:#"Staus ! "
message:#"Select your current status"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* online = [UIAlertAction
actionWithTitle:#"Online"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
[view dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* offline = [UIAlertAction
actionWithTitle:#"Offline"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[view dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* doNotDistrbe = [UIAlertAction
actionWithTitle:#"Do not disturb"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[view dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* away = [UIAlertAction
actionWithTitle:#"Do not disturb"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
[view dismissViewControllerAnimated:YES completion:nil];
}];
[online setValue:[[UIImage imageNamed:#"online.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forKey:#"image"];
[offline setValue:[[UIImage imageNamed:#"offline.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forKey:#"image"];
[doNotDistrbe setValue:[[UIImage imageNamed:#"DND.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forKey:#"image"];
[away setValue:[[UIImage imageNamed:#"away.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forKey:#"image"];
[view addAction:online];
[view addAction:away];
[view addAction:offline];
[view addAction:doNotDistrbe];
[self presentViewController:view animated:YES completion:nil];
You could add an image above the title label by subclassing UIAlertController and adding \n to the title string to make space for the UIImageView. You'd have to compute the layout based on the font size. For images in the UIAlertAction use KVC like so self.setValue(image, forKey: "image"). I would recommend to use an extension that checks for responds(to:). Here is sample implementation.
For swift
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let action = UIAlertAction(title: NSLocalizedString("Share", comment: ""), style: .default, handler: { _ in
})
let image = UIImage(named: "Temp1")
action.setValue(image?.withRenderingMode(.alwaysOriginal), forKey: "image")
actionSheet.addAction(action)
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
Note: IMP Line withRenderingMode(.alwaysOriginal)
Try something like this:
UIAlertView* alert = [UIAlertView alloc] initWithTitle: #"Test Alert" message: #"Alert With Custom View" delegate:nil cancelButtonTitle:#"NO" otherButtonTitles:#"YES", nil];
UIImage* imgMyImage = [UIImage imageNamed:#"myImage.png"];
UIImageView* ivMyImageView = [UIImageView alloc] initWithFrame:CGRectMake(0, 0, imgMyImage.size.width, imgMyImage.size.height)];
[ivMyImageView setImage:imgMyImage];
[alert setValue: ivMyImageView forKey:#"accessoryView"];
[alert show];
Tested this and it works for iOS 7.0
Swift Version:
actionBtn.setValue(UIImage.init(named: "completeDose"), forKey: "image")
swift code
let customActionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let firstButton = UIAlertAction(title: "First Button", style: .default, handler: { action in
//click action
})
firstButton.setValue(UIColor.black, forKey: "titleTextColor")
firstButton.setValue(UIColor.black, forKey: "imageTintColor")
firstButton.setValue(NSNumber(value: true), forKey: "checked")
let secondButton = UIAlertAction(title: "Second Button", style: .default, handler: { action in
//click action
})
secondButton.setValue(UIColor.black, forKey: "titleTextColor")
let cancelButton = UIAlertAction(title: "Cancel", style: .cancel, handler: { action in
//cancel
})
cancelButton.setValue(UIColor.black, forKey: "titleTextColor")
customActionSheet.addAction(firstButton)
customActionSheet.addAction(secondButton)
customActionSheet.addAction(cancelButton)
present(customActionSheet, animated: true)enter code here
swift 3 extension , property and convenience init.
extension UIAlertAction{
#NSManaged var image : UIImage?
convenience init(title: String?, style: UIAlertActionStyle,image : UIImage?, handler: ((UIAlertAction) -> Swift.Void)? = nil ){
self.init(title: title, style: style, handler: handler)
self.image = image
}
}
thanks to Shahar Stern for the inspiration