ios - 如何在 Swift 中为多个 UIActionSheet 创建通用方法

标签 ios swift uikit uialertcontroller

我正在设置一个带有 2 个 UIButtonsUIViewController。 每个按钮都有一个功能,该功能将显示一个带有几个选项的 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)
}

解决方案 2:

如果您的 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)
}

关于ios - 如何在 Swift 中为多个 UIActionSheet 创建通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55381078/

相关文章:

ios - 使用 NSPredicate 过滤包含字典的数组

ios - 我应该使用依赖注入(inject)而不是类函数吗?

ios - 如何访问 UIView 子类的成员

swift - 为什么我不能将 Protocol.Type 传递给通用 T.Type 参数?

iOS 表格 - iPad 和 iPhone 上的相同代码不同颜色

ios - 突出显示整个 UITableviewcell 而不是单元格内的圆形 View

ios - 在 Objective-c 中同步连接到 AWS DynamoDB

ios - Alertview 操作在快速导航到下一个 View Controller 后

Swift:表达式类型在没有更多上下文的情况下不明确

swift - 组合布局中的动态单元宽度