循环中的 AlertController
AlertController in a loop
我有一个功能可以显示最多列出 5 个项目(收藏夹)的警报,以允许用户 select 一个并使用它。我的代码有效,但看起来又长又乱,我试图在循环中简化它,但用户 selected 的项目总是 returns 循环值的结束。我的代码如下。它显示了我试图开始工作的循环逻辑(请注意,警报返回的索引始终是循环结束时 counter
的值(即无论点击哪个元素,useFavourite(5)
被调用。我也提供了有效的代码(但对我来说感觉很乱)。有没有更好的方法来实现简单性?
func showFavouritesAlert() -> Void {
//either shows a list of favourites or message stating no favourites
if userData.noFavourites {
let message = "You have no stored favourites. You can add to favourites by selecting the \u{2605} button."
let alertController = UIAlertController(title: "UK Tides", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true, completion: nil)
} else { //favourites are present so show them
let message = "Select one of your Tide Station favourites."
let alertController = UIAlertController(title: "UK Tides", message: message, preferredStyle: .alert)
//the loop below shows the correct alert but always executes useFavourites(5)
var counter = 0
for entry in userData.currentSelection.favourites {
alertController.addAction(UIAlertAction(title: entry.name, style: .default, handler: {(action) in
self.useFavourite(counter)
}))
counter += 1
}
//the code below works but feels long winded
let favourites = userData.currentSelection.favourites
let favCount = favourites.count
alertController.addAction(UIAlertAction(title: favourites[0].name, style: .default, handler: {(action) in
self.useFavourite(0)
}))
if favCount > 1 {
alertController.addAction(UIAlertAction(title: favourites[1].name, style: .default, handler: {(action) in
self.useFavourite(1)
}))
}
if favCount > 2 {
alertController.addAction(UIAlertAction(title: favourites[2].name, style: .default, handler: {(action) in
self.useFavourite(2)
}))
}
if favCount > 3 {
alertController.addAction(UIAlertAction(title: favourites[3].name, style: .default, handler: {(action) in
self.useFavourite(3)
}))
}
if favCount > 4 {
alertController.addAction(UIAlertAction(title: favourites[4].name, style: .default, handler: {(action) in
self.useFavourite(4)
}))
}
//the code above works
alertController.addAction(UIAlertAction(title: "Cancel", style: .default))
self.present(alertController, animated: true, completion: nil)
}
return
}
当然有更好的方法来做到这一点(例如使用 .enumerated()
而不是手动计数器),但要回答您的问题,您的闭包必须捕获 value 而不是捕获 reference(这是局部变量的默认值)。
var counter = 0
for entry in userData.currentSelection.favourites {
let action = UIAlertAction(title: entry.name, style: .default) { [counter] _ in
self.useFavourite(counter)
}
alertController.addAction(action)
counter += 1
}
以及没有局部变量的版本:
for (offset, entry) in userData.currentSelection.favourites.enumerated() {
let action = UIAlertAction(title: entry.name, style: .default) { _ in
self.useFavourite(offset)
}
alertController.addAction(action)
}
我有一个功能可以显示最多列出 5 个项目(收藏夹)的警报,以允许用户 select 一个并使用它。我的代码有效,但看起来又长又乱,我试图在循环中简化它,但用户 selected 的项目总是 returns 循环值的结束。我的代码如下。它显示了我试图开始工作的循环逻辑(请注意,警报返回的索引始终是循环结束时 counter
的值(即无论点击哪个元素,useFavourite(5)
被调用。我也提供了有效的代码(但对我来说感觉很乱)。有没有更好的方法来实现简单性?
func showFavouritesAlert() -> Void {
//either shows a list of favourites or message stating no favourites
if userData.noFavourites {
let message = "You have no stored favourites. You can add to favourites by selecting the \u{2605} button."
let alertController = UIAlertController(title: "UK Tides", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true, completion: nil)
} else { //favourites are present so show them
let message = "Select one of your Tide Station favourites."
let alertController = UIAlertController(title: "UK Tides", message: message, preferredStyle: .alert)
//the loop below shows the correct alert but always executes useFavourites(5)
var counter = 0
for entry in userData.currentSelection.favourites {
alertController.addAction(UIAlertAction(title: entry.name, style: .default, handler: {(action) in
self.useFavourite(counter)
}))
counter += 1
}
//the code below works but feels long winded
let favourites = userData.currentSelection.favourites
let favCount = favourites.count
alertController.addAction(UIAlertAction(title: favourites[0].name, style: .default, handler: {(action) in
self.useFavourite(0)
}))
if favCount > 1 {
alertController.addAction(UIAlertAction(title: favourites[1].name, style: .default, handler: {(action) in
self.useFavourite(1)
}))
}
if favCount > 2 {
alertController.addAction(UIAlertAction(title: favourites[2].name, style: .default, handler: {(action) in
self.useFavourite(2)
}))
}
if favCount > 3 {
alertController.addAction(UIAlertAction(title: favourites[3].name, style: .default, handler: {(action) in
self.useFavourite(3)
}))
}
if favCount > 4 {
alertController.addAction(UIAlertAction(title: favourites[4].name, style: .default, handler: {(action) in
self.useFavourite(4)
}))
}
//the code above works
alertController.addAction(UIAlertAction(title: "Cancel", style: .default))
self.present(alertController, animated: true, completion: nil)
}
return
}
当然有更好的方法来做到这一点(例如使用 .enumerated()
而不是手动计数器),但要回答您的问题,您的闭包必须捕获 value 而不是捕获 reference(这是局部变量的默认值)。
var counter = 0
for entry in userData.currentSelection.favourites {
let action = UIAlertAction(title: entry.name, style: .default) { [counter] _ in
self.useFavourite(counter)
}
alertController.addAction(action)
counter += 1
}
以及没有局部变量的版本:
for (offset, entry) in userData.currentSelection.favourites.enumerated() {
let action = UIAlertAction(title: entry.name, style: .default) { _ in
self.useFavourite(offset)
}
alertController.addAction(action)
}