Как создать общий метод для нескольких UIActionSheet в Swift - PullRequest
1 голос
/ 27 марта 2019

Я настраиваю 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?

Спасибо, если вы прочитали это.

Ответы [ 3 ]

1 голос
/ 27 марта 2019

Решение 1:

Если ваши действия AlertViewController всегда будут иметь результат, вы можете значительно уменьшить дублирование, как показано ниже, используя параметры struct и variadic:

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)
}
0 голосов
/ 27 марта 2019

Вы можете установить тег в каждом 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
  }

Надеюсь, это поможет!

0 голосов
/ 27 марта 2019

вы можете написать функцию, подобную этой

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

, выбрать переменные, которые должны быть необязательными

...