How to add UIActionSheet button check mark?
Asked Answered
D

5

18

I wonder how to add check mark to the right of actionSheet button the simplest way? Bellow is a screenshot of Podcasts app.

enter image description here

Disrespectable answered 17/11, 2016 at 4:59 Comment(6)
You need a custom alert since UIAlertController doesn't support such a feature.Tarazi
But the Podcasts app is using UIActionSheet, pls take a look at my screenshot.Disrespectable
Apple has access to any API it wants. But there is no public API to do what you want with UIAlertController.Tarazi
you can refer this link https://mcmap.net/q/673182/-uiactionsheet-checkmarkRonrona
I'm already did a research about this, but seem no simple way to do it without any customization.Disrespectable
@Tarazi finally I got my answer, thanks for your suggestion.Disrespectable
D
47

Note that the solution can crash in a future update to iOS. I'm accessing undocumented private APIs. Such solutions are very fragile. Please see the comments below.

Finally I got the answer by using UIAlertController:

UIAlertController *customActionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];

UIAlertAction *firstButton = [UIAlertAction actionWithTitle:@"First Button" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
    //click action
}];
[firstButton setValue:[UIColor blackColor] forKey:@"titleTextColor"];
[firstButton setValue:[UIColor blackColor] forKey:@"imageTintColor"];
[firstButton setValue:@true forKey:@"checked"];

UIAlertAction *secondButton = [UIAlertAction actionWithTitle:@"Second Button" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
    //click action
}];
[secondButton setValue:[UIColor blackColor] forKey:@"titleTextColor"];

UIAlertAction *cancelButton = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
    //cancel
}];
[cancelButton setValue:[UIColor blackColor] forKey:@"titleTextColor"];

[customActionSheet addAction:firstButton];
[customActionSheet addAction:secondButton];
[customActionSheet addAction:cancelButton];

[self presentViewController:customActionSheet animated:YES completion:nil];

And this is the result:

UIActionSheet button check mark

Disrespectable answered 17/11, 2016 at 17:57 Comment(7)
Note that your solution can crash in a future update to iOS. You are accessing undocumented private APIs. Such solutions are very fragile.Tarazi
can you add the answer for modify the uialertaction text font,Roxannroxanna
@Roxannroxanna I will try it and update to github.com/jaredchu/JCActionSheet. Please note that solution can crash in a future update to iOS, so be careful if you use this solution for a production project.Disrespectable
@Roxannroxanna hi, it seems no way to change the font of UIAlertAction via hidden api, you can take a look here: github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/…Disrespectable
@JaredChu - ya we can't change ,its comes in third layer,Roxannroxanna
@JaredChu Those are synthesized getters and setters for a KVC property, still internal onlyTien
You are right, but it's the easiest way. I added a notice because this post is getting more views.Disrespectable
B
8

Swift Version: 4.1

I came across this implementation using creating extension over UIAlertController.

extension UIAlertController {
static func actionSheetWithItems<A : Equatable>(items : [(title : String, value : A)], currentSelection : A? = nil, action : @escaping (A) -> Void) -> UIAlertController {
    let controller = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    for (var title, value) in items {
        if let selection = currentSelection, value == selection {
            // Note that checkmark and space have a neutral text flow direction so this is correct for RTL
            title = "✔︎ " + title
        }
        controller.addAction(
            UIAlertAction(title: title, style: .default) {_ in
                action(value)
            }
        )
    }
    return controller
}

}

Implementation:

   func openGenderSelectionPopUp() {
     let selectedValue = "Men" //update this for selected value
     let action = UIAlertController.actionSheetWithItems(items: [("Men","Men"),("Women","Women"),("Both","Both")], currentSelection: selectedValue, action: { (value)  in
        self.lblGender.text = value
     })
     action.addAction(UIAlertAction.init(title: ActionSheet.Button.cancel, style: UIAlertActionStyle.cancel, handler: nil))
     //Present the controller
     self.present(action, animated: true, completion: nil)
}

Final Result:

Select Gender

Hope that helps!

Thanks

Borsch answered 26/7, 2018 at 9:54 Comment(0)
M
4

Another option is just to add a check mark character to a button title, like this "Title ✓". It will be next to the title, not at the right side of the button, but I think it's not a very big problem.

Mamey answered 17/7, 2018 at 8:11 Comment(1)
Thanks, It's maybe the simplest wayDisrespectable
N
4

Swift implementation:

class Controller: UIViewController {

    var isFirstButtonChecked = true

    @IBAction func buttonTapped(_ sender: UIButton?) {
        let firstButton = UIAlertAction(title: "First Button", style: .default, handler: { [unowned self] _ in
            self.isFirstButtonChecked = true
            print("First Button tapped")
        })
        //Here's the main magic; it's called Key-Value Coding, or KVC:
        firstButton.setValue(isFirstButtonChecked, forKey: "checked")

        let secondButton = UIAlertAction(title: "Second Button", style: .default, handler: { [unowned self] _ in
            self.isFirstButtonChecked = false
            print("Second Button tapped")
        })
        secondButton.setValue(!isFirstButtonChecked, forKey: "checked")

        let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

        alert.addAction(firstButton)
        alert.addAction(secondButton)
        alert.addAction(cancel)
        self.present(alert, animated: true, completion: nil)
    }
}

You can also provide checkmark for bigger number of buttons using an enum:

class Controller: UIViewController {

    enum ButtonChecked {
        case first
        case second
        case third
        case forth
    }

    var buttonChecked: ButtonChecked = .first

    @IBAction func buttonTapped(_ sender: UIButton?) {
        let firstButton = UIAlertAction(title: "First Button", style: .default, handler: { [unowned self] _ in
            self.buttonChecked = .first
            print("First Button tapped")
        })

        let secondButton = UIAlertAction(title: "Second Button", style: .default, handler: { [unowned self] _ in
            self.buttonChecked = .second
            print("Second Button tapped")
        })

        let thirdButton = UIAlertAction(title: "Third Button", style: .default, handler: { [unowned self] _ in
            self.buttonChecked = .third
            print("Third Button tapped")
        })

        let forthButton = UIAlertAction(title: "Forth Button", style: .default, handler: { [unowned self] _ in
            self.buttonChecked = .forth
            print("Forth Button tapped")
        })

        let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        switch buttonChecked {
        case .first:
            firstButton.setValue(true, forKey: "checked")
        case .second:
            secondButton.setValue(true, forKey: "checked")
        case .third:
            thirdButton.setValue(true, forKey: "checked")
        case .forth:
            forthButton.setValue(true, forKey: "checked")
        }

        let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

        alert.addAction(firstButton)
        alert.addAction(secondButton)
        alert.addAction(thirdButton)
        alert.addAction(forthButton)
        alert.addAction(cancel)
        self.present(alert, animated: true, completion: nil)
    }
}
Numerous answered 19/5, 2019 at 11:43 Comment(0)
P
0

Try this trick :

  • Learn how to show a ViewController as a pop-up
    • Add UITable to a ViewController
    • Show items in a UITable
    • Customize the UITable by adding custom cells
    • In each of the custom cells add a button
    • That button will have two kinds of images, one blank box and the other box with a check mark
    • when user touches a table cell you need to change the button image corresponding to that table row so the user thinks they are checking or unchecking the box
    • and lastly add a done button at the bottom to dismiss the viewcontroller

Google all these items for tutorials. As I said this is not a simple task as there is no out of the box check mark function in Xcode.

From : https://mcmap.net/q/673183/-checkbox-in-uialertcontroller-with-actionsheet-in-objective-c-duplicate

Perishable answered 17/11, 2016 at 5:20 Comment(2)
I got my own answer, it's very simple :DDisrespectable
Please don't repost a previous answer (especially one you copied from someone else prior to that). Instead, vote to close as a duplicate.Tarazi

© 2022 - 2024 — McMap. All rights reserved.