如何添加UIActionSheet按钮的勾选标记?

18

我想知道最简单的方法是如何在操作表按钮右侧添加检查标记? 下面是 Podcasts 应用程序的屏幕截图。

输入图片描述


1
由于UIAlertController不支持此功能,因此您需要自定义警报。 - rmaddy
但是Podcasts应用程序正在使用UIActionSheet,请查看我的屏幕截图。 - Jared Chu
1
苹果可以访问任何它想要的API。但是没有公共API可以做你想要的UIAlertController - rmaddy
你可以参考这个链接 https://dev59.com/EoXca4cB1Zd3GeqPGErp - Parth Bhuva
我已经对此进行了研究,但似乎没有简单的方法可以在不进行任何自定义的情况下完成它。 - Jared Chu
@rmaddy,终于得到了答案,感谢您的建议。 - Jared Chu
5个回答

47

请注意,此解决方案在iOS的未来更新中可能会崩溃。我正在访问未经记录的私有API。这样的解决方案非常脆弱。请参阅下面的评论。

最终我使用了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];

这是结果:

UIActionSheet button check mark


2
请注意,您的解决方案可能在未来的iOS更新中崩溃。您正在访问未经记录的私有API。这样的解决方案非常脆弱。 - rmaddy
1
你能否添加修改UIAlertAction文本字体的答案? - Anbu.Karthik
@Anbu.Karthik 我会尝试并更新到https://github.com/jaredchu/JCActionSheet。请注意,`解决方案在iOS的未来更新中可能会崩溃`,因此如果您将此解决方案用于生产项目,请小心。 - Jared Chu
1
@JaredChu - 哎呀,我们不能更改,它是在第三层中出现的。 - Anbu.Karthik
1
@JaredChu 这些是用于 KVC 属性的合成 getter 和 setter,仍然仅限内部使用。 - Allison
显示剩余2条评论

8

Swift版本:4.1

我发现了这个使用创建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
}

}

实现:

   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)
}

最终结果:

选择性别

希望这有所帮助!

谢谢


4
另一个选项是在按钮标题中添加勾选符号,例如 "Title ✓"。它将显示在标题旁边而不是按钮右侧,但我认为这并不是一个很大的问题。

1
谢谢,这可能是最简单的方法。 - Jared Chu

4

Swift实现:

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)
    }
}

您还可以使用枚举(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)
    }
}

0

试试这个小技巧:

  • 学习如何将ViewController显示为弹出窗口
    • 在ViewController中添加UITable
    • 在UITable中显示项目
    • 通过添加自定义单元格来自定义UITable
    • 在每个自定义单元格中添加一个按钮
    • 该按钮将具有两种图像,一种是空白框,另一种是带有勾选标记的框
    • 当用户触摸表格单元格时,您需要更改与该表格行对应的按钮图像,以便用户认为他们正在选中或取消选择框
    • 最后,在底部添加一个完成按钮以关闭视图控制器

Google搜索这些项目以获取教程。正如我所说,这不是一个简单的任务,因为Xcode中没有开箱即用的勾选标记功能。

来自: https://stackoverflow.com/a/40542931/3901620


我得到了自己的答案,非常简单 :D - Jared Chu
1
请不要重新发布之前的回答(尤其是你在那之前复制别人的回答)。相反,请投票关闭为重复问题。 - rmaddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接