UIAlertController' UIAlertAction'标签/用户数据或Swift

时间:2015-05-17 11:26:56

标签: ios swift uialertcontroller

在我的iOS动态表中,我显示了JSON字典中的名称:

[
  { "Name": "Doctor for Disease AAA",
    "Doctor_id": "21"
  },
  { "Name": "Doctor for Disease BBB",
    "Doctor_id": "22"
  },
  { "Name": "Doctor for Disease AAA",
    "Doctor_id": "25"
  }
]

因此,在按钮点击委托上,我可以获得按钮索引,并可以获取相应的'名称'和' Doctor_id'。这很好。

但是现在好像' UIActionSheet'不推荐使用,我必须使用' UIAlertController'。因为我有一个大数据,我正在遍历我的数组值并调用alertcontroller处理程序(所以单击所有按钮的单个函数)。但是如何从UIAlertController获取按钮索引,以便我可以获取' Name'和' Doctor_id'同时。

请帮帮我。

6 个答案:

答案 0 :(得分:14)

这里有多种可能性。

您可以使用find获取UIAlertAction索引

find可以让你找到数组中对象的索引。您可以使用它find action的索引(作为UIAlertAction处理程序的参数传递,这是UIAlertAction本身)在所有操作的alert.actions数组中。

let alert = UIAlertController(title: "Doctors", message: "Choose a doctor", preferredStyle: .ActionSheet)
let closure = { (action: UIAlertAction!) -> Void in
    let index = find(alert.actions as! [UIAlertAction], action)
    println("Index: \(index)")
}
alert.addAction(UIAlertAction(title: "Doc1", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Doc2", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Doc3", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Doc4", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel) { _ in
    println("User cancelled.")
})
self.presentViewController(alert, animated: true) {}

您可以创建一个闭包...返回一个闭包

创建一个闭包,它接受您选择的参数(此处为Int)并返回一个捕获该参数的闭包,以便您可以使用它

 let alert = UIAlertController(title: "Doctors", message: "Choose a doctor", preferredStyle: .ActionSheet)
 let closure = { (index: Int) in
     { (action: UIAlertAction!) -> Void in
         println("Index: \(index)")
     }
 }
 alert.addAction(UIAlertAction(title: "Doc1", style: .Default, handler: closure(0)))
 alert.addAction(UIAlertAction(title: "Doc2", style: .Default, handler: closure(1)))
 alert.addAction(UIAlertAction(title: "Doc3", style: .Default, handler: closure(2)))
 alert.addAction(UIAlertAction(title: "Doc4", style: .Default, handler: closure(3)))
 alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel) { _ in
     println("User cancelled.")
 })
 self.presentViewController(alert, animated: true) {}

这样你就有一个函数(闭包)为你的UIAlertAction处理程序生成闭包,除了它们捕获一个不同的对象(这里有一个不同的Int)之外,它们都有相同的主体。

这个解决方案的真正优点是你可以捕获任何东西。您甚至可以捕获代表您的医生的假设Doctor对象,或直接捕获医生ID等!

使用循环

但通常你会使用for循环添加你的动作,所以为什么不利用它,加上利用闭包和它们捕获变量的事实,做一个很好的函数,直接告诉你选定的医生的身份证?

func testMyAlert() {
    let doctors = [
        ["Name": "Doctor for Disease AAA", "Doctor_id": "21"],
        ["Name": "Doctor for Disease BBB", "Doctor_id": "22"],
        ["Name": "Doctor for Disease AAA", "Doctor_id": "25"]
    ]

    chooseDoctor(doctors) { selectedDocID in
        if let docID = selectedDocID {
            println("User selected doctor with ID \(docID)")
        } else {
            println("User cancelled, no doctor selected")
        }
    }
}

func chooseDoctor(doctors: Array<[String:String]>, completion: Int?->Void) {
    let alert = UIAlertController(title: "Doctors", message: "Choose a doctor", preferredStyle: .ActionSheet)
    for doc in doctors {
        let action = UIAlertAction(title: doc["Name"]!, style: UIAlertActionStyle.Default) { _ in
            // On selecting this action, get the doctor's ID, convert it to an Int, and return that.
            completion(doc["Doctor_id"]?.toInt())
        }
        alert.addAction(action)
    }
    alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { _ in completion(nil) } )
    self.presentViewController(alert, animated: true) {}

}

答案 1 :(得分:5)

您可以按以下方式解决问题:

let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney", ... ]

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

let closure = { (action: UIAlertAction!) -> Void in 
    let index = alert.actions.indexOf(action)
    if index != nil {
        NSLog("Index: \(index!)") 
    }
}

for var i = 0; i < arrayBibleVersions.count; i++ { alert.addAction(UIAlertAction(title: arrayBibleVersions[i][1], style: .Default, handler: closure)) }

alert.addAction(UIAlertAction(title: "cancel", style: .Cancel, handler: {(_) in }))

self.presentViewController(alert, animated: false, completion: nil)

答案 2 :(得分:3)

您可以通过控制器对您的一系列操作发送indexOf(element: Self.Generator.Element)

类似的东西:

let actionSheetController = UIAlertController(title: "Title", message: "Select Title", 
                                              preferredStyle: UIAlertControllerStyle.ActionSheet);

for entry in data {
   let myAction = UIAlertAction(title: "title: \(entry)", style: UIAlertActionStyle.Default) { (action) -> Void in
      if let alertIndex = actionSheetController.actions.indexOf(action) {
        print("actionIndex: \(alertIndex)")
      }
   }
   actionSheetController.addAction(myAction)
}

答案 3 :(得分:0)

我建议您在需要时通过闭包来打电话。它随需应变。也许这样的事情会有所帮助。

var alert = UIAlertController(title: "Title", message: "do this", preferredStyle: UIAlertControllerStyle.ActionSheet)
    var action = UIAlertAction(title: "Doc1", style: UIAlertActionStyle.Default) { (action) -> Void in
        //do some work here
    }

但同样,我猜你在动作表上没有显示超过4个项目,因为它对设计不利。关闭可能是一个好主意。建议我,如果我弄错了,我很乐意帮助你。欢呼声。

答案 4 :(得分:0)

通过创建一个或多个UIAlertAction对象并将其附加到警报控制器,可以将按钮添加到UIAlertController。每个警报操作都有一个标题(用于创建它的按钮)和一个在用户点击该按钮时调用的闭包。

您是说要为所有按钮使用相同的闭包?我看到了很多选择

  1. 您可以为每个警报操作编写唯一的闭包,其中闭包只是调用共享函数并传入按钮编号。

  2. 或者,UIAlertAction的闭包在被点击的按钮的标题中传递。您可以使用它来决定点击了哪个按钮。 (这很脆弱,因为按钮标题可能是本地化的,并且可能因UI原因而发生变化。当UI更改破坏代码时,它很糟糕。)

  3. 作为最终选项,您可以使用关联存储将对象附加到每个UIAlertAction,并使用它来确定点击了哪个按钮。

  4. 我的建议是选项1.它简单而干净。

答案 5 :(得分:0)

我发现使用自定义UIAlertAction类比使用索引更容易且更具表达力

class MyAlertAction:UIAlertAction {
    var key:String = ""
    convenience init(key:String, title:String, handler:((UIAlertAction) -> ())?) {
        self.init(title: title, style: .default, handler: handler)
        self.key = key
    }
}

在动作处理程序中,您将获得如下所示的密钥:

let actionHandler: (UIAlertAction) -> () = { (action) in
    if let key = (action as? MyAlertAction)?.key {
         //use the key
    }
}

最终使用您的新类添加一个动作

alert.addAction(MyAlertAction(key:"doctor32", title: "Title", handler: actionHandler))