Swift - 如何从 UIActionSheet 更新自定义单元格标签

问题描述

我有一个带有标题标签自定义集合视图单元格子类。我想将单元格的标题标签更改为操作表中所选操作的标题。我尝试在处理程序中执行此操作,但无法通过处理程序访问单元格标签

这是操作表的代码

func dailyInjuryIllnessActionSheet() {
        let alert = UIAlertController(title: "Title",message: "Select an Option",preferredStyle: .actionSheet)
        //alert.addAction(UIAlertAction(title: "Available for Full Participation",style: .default,handler: nil))
        alert.addAction(UIAlertAction(title: "Available for Full Participation",handler: { (action) in
            /// Change the cell text - Get the `UILabel`,and replace the text with `action.title`
            

        }))
        alert.addAction(UIAlertAction(title: "Available for Limited Participation",handler: nil))
        alert.addAction(UIAlertAction(title: "Not Available For Participation",handler: nil))
        alert.addAction(UIAlertAction(title: "Close Injury / Illness",handler: nil))
        alert.addAction(UIAlertAction(title: "Cancel",style: .destructive,handler: nil))
        present(alert,animated: true,completion: nil)
    }

这是单元格的代码

func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DIISDetailCell.reuseIdentifier,for: indexPath) as? DIISDetailCell else { return UICollectionViewCell() }
        if let entries = player?.entries {
            for entry in entries {
                cell.eventName.text = entry.injuryIllnessName
                cell.eventDate.text = entry.statusDate.formatted()
                cell.eventType.text = entry.status
                cell.modifiedBy.text = entry.modifiedBy ?? "Modified By Goes Here"
                
            }
        }
        return cell
    }

我整个星期都在坚持这个。

我在哪里调用代码

func collectionView(_ collectionView: UICollectionView,didSelectItemAt indexPath: IndexPath) {
        dailyInjuryIllnessActionSheet()
    }

解决方法

一旦用户从警报中做出选择,您就需要更新模型数据(以及随后的单元格标签)。警报选择异步。您可以使用几种常见的方法。一是委托。另一种是传递一个完成处理程序闭包。第二个更Swifty,这是我将使用的。

首先,您的 cellForItemAt 中有错误 - 它将为每个单元格调用,因此您不应该有 for 循环 - 您需要根据 IndexPath.item 访问所需元素{1}}。这是一个您通常会使用强制向下转换和强制展开的函数,因为需要注册单元格类,如果您没有条目(或没有 numberOfItems),您的 player 函数应该返回 0 -

func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DIISDetailCell.reuseIdentifier,for: indexPath) as! DIISDetailCell
    let entry = player!.entries[indexPath.item]
    cell.eventName.text = entry.injuryIllnessName
    cell.eventDate.text = entry.statusDate.formatted()
    cell.eventType.text = entry.status
    cell.modifiedBy.text = entry.modifiedBy ?? "Modified By Goes Here"
               
    return cell
}

您可以通过为选项使用数组来稍微简化您的 dailyInjuryIllnessActionSheet 代码。为简单起见,我在函数中声明了数组,但它可能应该从其他一些信息源传入。

向此函数添加一个 completion 处理程序参数以将所选选项传回给调用者:

func dailyInjuryIllnessActionSheet(completion:((String?)->Void)?=nil) {
    
    let options = ["Available for Full Participation","Available for Limited Participation","Not Available For Participation","Close Injury / Illness"
    ]
    let alert = UIAlertController(title: "Title",message: "Select an Option",preferredStyle: .actionSheet)
    
    for option in options {
        alert.addAction(UIAlertAction(title: option,style: .default,handler: { action in 
            completion?(option)
        }))
    }
    alert.addAction(UIAlertAction(title: "Cancel",style: .destructive,handler: { action in
        completion?(nil)
    }))
    present(alert,animated: true,completion: nil)
}

现在您可以在调用 dailyInjuryIllnessActionSheet 更新模型并重新加载项目时传递完成处理程序:

func collectionView(_ collectionView: UICollectionView,didSelectItemAt indexPath: IndexPath) {
    dailyInjuryIllnessActionSheet() { selectedOption in {
        guard let selectedOption = selectedOption else {
            return
        }
        player!.entries[indexPath.item].status = selectedOption
        collectionView.reloadItems(at:[indexPath])
    }
  
}