如何在 Swift 中为多个 UIActionSheet 创建通用方法
How to create a general method for multiple UIActionSheet in Swift
我正在设置一个 UIViewController
和 2 UIButtons
。
每个按钮都有一个功能,显示 UIAlertController
和几个选项。
可以创建一个通用方法来避免两个函数中的代码重复吗?
我已经尝试创建一个参数类型为 UIAlertController
的函数,但我无法使用该参数。
我在这里创建了一个示例来向您展示我尝试重构的内容:
func showFirstMenu(){
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let optionOne = UIAlertAction(title: "Option 1", style: .default) { action in
self.performSegue(withIdentifier: "optionOne", sender: self)
}
let optionTwo = UIAlertAction(title: "Option 2", style: .default) { action in
self.performSegue(withIdentifier: "optionTwo", sender: self)
}
actionSheet.addAction(optionOne)
actionSheet.addAction(optionTwo)
actionSheet.addAction(cancel)
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPad")
}
else{
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPhone")
}
}
func showSecondMenu(){
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let optionThree = UIAlertAction(title: "Option 3", style: .default) { action in
self.performSegue(withIdentifier: "optionThree", sender: self)
}
let optionFour = UIAlertAction(title: "Option 4", style: .default) { action in
self.performSegue(withIdentifier: "optionFour", sender: self)
}
actionSheet.addAction(optionThree)
actionSheet.addAction(optionFour)
actionSheet.addAction(cancel)
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPad")
}
else{
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPhone")
}
}
有什么方法可以减少代码量吗?或者这是声明 UIActionSheet
?
的唯一方法
感谢您阅读本文。
解决方案一:
如果您的 AlertViewController
的操作将始终有 segue 执行,您可以使用结构和可变参数显着减少重复,如下所示:
struct Option {
var name: String
var segueIdentifier: String
}
func configureActionSheet(options: Option...) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(cancel)
for option in options {
let currentOption = UIAlertAction(title: option.name, style: .default) { action in
self.performSegue(withIdentifier: option.segueIdentifier, sender: self)
}
actionSheet.addAction(currentOption)
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
}
self.present(actionSheet, animated: true, completion: nil)
}
func showMenu1() {
let option1 = Option(name: "Option 1", segueIdentifier: "optionOne")
let option2 = Option(name: "Option 2", segueIdentifier: "optionTwo")
self.configureActionSheet(options: option1, option2)
}
方案二:
如果您的 AlertViewController
的操作总是不同,那么您无能为力,但仍然可以避免重复,如下所示:
func configureActionSheet() -> UIAlertController {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(cancel)
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
}
return actionSheet
}
func showFirstMenu() {
let optionOne = UIAlertAction(title: "Option 1", style: .default) { action in
self.performSegue(withIdentifier: "optionOne", sender: self)
}
let optionTwo = UIAlertAction(title: "Option 2", style: .default) { action in
self.performSegue(withIdentifier: "optionTwo", sender: self)
}
let actionSheet = configureActionSheet()
actionSheet.addAction(optionOne)
actionSheet.addAction(optionTwo)
self.present(actionSheet, animated: true, completion: nil)
}
你可以这样写一个函数
func presentActionsheetWithOptions(title:String, msg: String, options:[String:String], isCancelRequired:Bool) {
let actionSheet = UIAlertController(title: title, message: msg, preferredStyle: .actionSheet)
for (header,seg) in options {
let optionOne = UIAlertAction(title: header, style: .default) { action in
self.performSegue(withIdentifier: seg, sender: self)
}
actionSheet.addAction(optionOne)
}
if(isCancelRequired) {
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(cancel)
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPad")
}
else{
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPhone")
}
}
像这样调用函数
presentActionsheetWithOptions(title: "test", msg: "testmsg", options: ["option1":"optionone","option2":"optiontwo"], isCancelRequired: true);
决定应该是可选的变量
您可以像这样在每个 UIButton
中设置一个标签:
//For the first button
UIButton.tag = 1
//For the second button
UIButton.tag = 2
然后,您将此标记传递到您的菜单函数中,创建一个包含您的 UIAlertAction
标题和标识符的数组,循环它们并使用 switch 方法将适当的操作添加到警报中:
func showMenu(sender: UIButton) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let titles = ["Option 1", "Option 2", "Option 3", "Option 4"]
let identifiers = ["optionOne","optionTwo","optionThree","optionFour"]
let tags = [1,1,2,2] //match the button tag with the array index
for (index, title) in titles.enumerated(){
if sender.tag == tags[index] {
let action = self.getAction(title: title, identifier:identifiers[index])
actionSheet.addAction(action)
}
}
actionSheet.addAction(cancel)
}
func getAction(title: String, identifier: String) -> UIAlertAction {
let action = (title: title, style: .default) { action in
self.performSegue(withIdentifier: identifier, sender: self)
}
return action
}
希望对您有所帮助!
我正在设置一个 UIViewController
和 2 UIButtons
。
每个按钮都有一个功能,显示 UIAlertController
和几个选项。
可以创建一个通用方法来避免两个函数中的代码重复吗?
我已经尝试创建一个参数类型为 UIAlertController
的函数,但我无法使用该参数。
我在这里创建了一个示例来向您展示我尝试重构的内容:
func showFirstMenu(){
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let optionOne = UIAlertAction(title: "Option 1", style: .default) { action in
self.performSegue(withIdentifier: "optionOne", sender: self)
}
let optionTwo = UIAlertAction(title: "Option 2", style: .default) { action in
self.performSegue(withIdentifier: "optionTwo", sender: self)
}
actionSheet.addAction(optionOne)
actionSheet.addAction(optionTwo)
actionSheet.addAction(cancel)
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPad")
}
else{
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPhone")
}
}
func showSecondMenu(){
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let optionThree = UIAlertAction(title: "Option 3", style: .default) { action in
self.performSegue(withIdentifier: "optionThree", sender: self)
}
let optionFour = UIAlertAction(title: "Option 4", style: .default) { action in
self.performSegue(withIdentifier: "optionFour", sender: self)
}
actionSheet.addAction(optionThree)
actionSheet.addAction(optionFour)
actionSheet.addAction(cancel)
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPad")
}
else{
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPhone")
}
}
有什么方法可以减少代码量吗?或者这是声明 UIActionSheet
?
感谢您阅读本文。
解决方案一:
如果您的 AlertViewController
的操作将始终有 segue 执行,您可以使用结构和可变参数显着减少重复,如下所示:
struct Option {
var name: String
var segueIdentifier: String
}
func configureActionSheet(options: Option...) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(cancel)
for option in options {
let currentOption = UIAlertAction(title: option.name, style: .default) { action in
self.performSegue(withIdentifier: option.segueIdentifier, sender: self)
}
actionSheet.addAction(currentOption)
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
}
self.present(actionSheet, animated: true, completion: nil)
}
func showMenu1() {
let option1 = Option(name: "Option 1", segueIdentifier: "optionOne")
let option2 = Option(name: "Option 2", segueIdentifier: "optionTwo")
self.configureActionSheet(options: option1, option2)
}
方案二:
如果您的 AlertViewController
的操作总是不同,那么您无能为力,但仍然可以避免重复,如下所示:
func configureActionSheet() -> UIAlertController {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(cancel)
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
}
return actionSheet
}
func showFirstMenu() {
let optionOne = UIAlertAction(title: "Option 1", style: .default) { action in
self.performSegue(withIdentifier: "optionOne", sender: self)
}
let optionTwo = UIAlertAction(title: "Option 2", style: .default) { action in
self.performSegue(withIdentifier: "optionTwo", sender: self)
}
let actionSheet = configureActionSheet()
actionSheet.addAction(optionOne)
actionSheet.addAction(optionTwo)
self.present(actionSheet, animated: true, completion: nil)
}
你可以这样写一个函数
func presentActionsheetWithOptions(title:String, msg: String, options:[String:String], isCancelRequired:Bool) {
let actionSheet = UIAlertController(title: title, message: msg, preferredStyle: .actionSheet)
for (header,seg) in options {
let optionOne = UIAlertAction(title: header, style: .default) { action in
self.performSegue(withIdentifier: seg, sender: self)
}
actionSheet.addAction(optionOne)
}
if(isCancelRequired) {
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(cancel)
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet.popoverPresentationController?.sourceView = self.view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPad")
}
else{
self.present(actionSheet, animated: true, completion: nil)
print("Display on iPhone")
}
}
像这样调用函数
presentActionsheetWithOptions(title: "test", msg: "testmsg", options: ["option1":"optionone","option2":"optiontwo"], isCancelRequired: true);
决定应该是可选的变量
您可以像这样在每个 UIButton
中设置一个标签:
//For the first button
UIButton.tag = 1
//For the second button
UIButton.tag = 2
然后,您将此标记传递到您的菜单函数中,创建一个包含您的 UIAlertAction
标题和标识符的数组,循环它们并使用 switch 方法将适当的操作添加到警报中:
func showMenu(sender: UIButton) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let titles = ["Option 1", "Option 2", "Option 3", "Option 4"]
let identifiers = ["optionOne","optionTwo","optionThree","optionFour"]
let tags = [1,1,2,2] //match the button tag with the array index
for (index, title) in titles.enumerated(){
if sender.tag == tags[index] {
let action = self.getAction(title: title, identifier:identifiers[index])
actionSheet.addAction(action)
}
}
actionSheet.addAction(cancel)
}
func getAction(title: String, identifier: String) -> UIAlertAction {
let action = (title: title, style: .default) { action in
self.performSegue(withIdentifier: identifier, sender: self)
}
return action
}
希望对您有所帮助!