【问题标题】:Checking if cells are selected or not when button is pressed swift快速按下按钮时检查是否选择了单元格
【发布时间】:2018-09-18 09:34:49
【问题描述】:

在这张照片中,您可以看到用户可以打开或关闭每个单元格的开关。最后,当用户按下按钮时,我需要将选定的单元格(打开开关的单元格)添加到数组中以将其发送到 API。

当用户点击按钮(在屏幕底部)时,我应该得到 unitNopersonId 并将它们存储在我的结构中

我的模特:

struct Itemm : Codable {
    var unitNo:Int?
    var personId:Int?
}
struct welcome {
    var items : [Itemm?]
}

我必须发送如下数组:

{
  "items": [
    {
      "unitNo": 0,
      "personId": 0
    }
  ]
}

我对如何使用 if 语句访问 UIButton 中的单元格数据然后存储它们感到有些困惑。如果有任何帮助,我将不胜感激。

表格视图:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "SmsCell") as? SmsTableViewCell

    cell?.PhonNumberLbl.text = data![indexPath.section].contacts[indexPath.row]?.phoneNumber
    cell?.NameLbl.text = data![indexPath.section].contacts[indexPath.row]?.name
    cell?.selectedTF.isOn = (data![indexPath.section].contacts[indexPath.row]?.selected)!

    return cell!
}

API 响应:

 [
    {
        "contacts": [
            {
                "id": 9827,
                "selected": true,
                "phoneNumber": "09203137745",
                "name": "owner"
            },
            {
                "id": 10159,
                "selected": true,
                "phoneNumber": "08523698522",
                "name": "hff"
            },
            {
                "id": 10161,
                "selected": true,
                "phoneNumber": "09586731218",
                "name": "hjdldue"
            }
        ],
        "unitNo": 1,
        "unitPlaque": "jack",
        "billText": "texttext"
    },
    {
        "contacts": [
            {
                "id": 10145,
                "selected": true,
                "phoneNumber": "09123809556",
                "name": "mmm"
            },
            {
                "id": 10160,
                "selected": true,
                "phoneNumber": "85233366888",
                "name": "ttt"
            }
        ],
        "unitNo": 2,
        "unitPlaque": "mm",
        "billText": "texttext"
    }
]

我想我没有清楚地解释我在寻找什么。

我调用的第一个方法是GET 方法,它提供了我在表格中呈现的数据。用户只能更改开关,用户可以根据需要更改多次,直到他/她按下按钮(在屏幕底部)。

按下按钮时,我需要获取每个单元格后面的隐藏数据并将它们存储在我的结构中并将其发送到具有另一种方法的 API。当用户按下按钮时,我需要从打开了开关的单元格中提取 2 个属性。

Presenter 表示:

func sendSmsForAllTheMembers(AptId:String , data:[String:Int])
{
    ApiGenerator.request(targetApi: ApartemanService.sendSms(aptId: AptId, data: data), responseModel: Nil.self, success: { (response) in
        if response.response.statusCode == 200 {
            self.view?.SendingSmsSuccess()
        }else {
            do{

                var errorMessage = try response.response.mapString()
                errorMessage = errorMessage.replacingOccurrences(of: "\"", with: "",
                                                                 options: NSString.CompareOptions.literal, range:nil)

                self.view?.SendingSmsFailed(errorMessage: errorMessage)

            }catch let error{
                print(error)
                self.view?.SendingSmsFailed(errorMessage: "error")
            }

        }

    }) { (error) in
        self.view?.SendingSmsFailed(errorMessage: "error")
    }
}

【问题讨论】:

  • 您能否提供有关如何制作开关的代码?
  • 进行开关是什么意思?我从 API 收到一些数据,它有一个选定的变量,如果该选定的变量为真,那么开关将打开
  • 啊哈,如果数据被选中,你需要打开开关吗?
  • 好的,您能否提供有关如何填充 tableView 中的单元格的代码?以及来自 API 的数据对象?
  • 附注。字体有点太小,navBar 中文本的颜色与其背景没有很好的对比。 Che bamazze neveshti 'Ethan Hunt' ro :D

标签: ios swift uitableview


【解决方案1】:

您的第一个问题是您需要以某种方式将开关状态存储在视图控制器中;您不能将其直接存储在单元格中,因为单元格会在表格视图滚动时重复使用。

虽然您可以将开关状态存储在模型结构中,但我可能不会这样做,因为它会使您的结构可变。我会使用Set<IndexPath> 来跟踪选择。

您的下一个问题是知道何时更改单元格中的开关。你可以为你的UITableviewCell 子类提供一个闭包来处理这个问题。

SmsCell

var switchHandler: ((Bool)->Void)?

@IBAction func switchChanged(_ sender: UISwitch) {
    self.switchHandler?(sender.isOn)
}

视图控制器

var selectedCells = Set<IndexPath>()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "SmsCell") as! SmsTableViewCell

    let cellData = self.data![indexPath.section]
    let contact = cellData.contacts[indexPath.row]

    cell.PhonNumberLbl.text = contact.phoneNumber
    cell.NameLbl.text = contact.name
    cell.selectedTF.isOn = self.selectedCells.contains(indexPath)
    cell.switchHandler = { (switchState) in
        if switchState {
            self.selectedCells.insert(indexPath)
        } else {
            self.selectedCells.remove(indexPath)
        }
    }

    return cell
}

您的最终任务是创建可以编码为所需 JSON 的结构:

struct Itemm: Codable {
    let unitNo: Int
    let personId: Int
}

struct Welcome: Codable {
    var items:[Itemm]
}

视图控制器

@IBAction func sendButtonTapped(_ sender: UIButton) {

   var items = [Itemm]() 
   for indexPath in self.selectedCells {
       let data = self.data![indexPath.section]
       let contact = data.contacts[indexPath.row]
       let newItem = Itemm(unitNo: data.unitNo, personId: contact.id)
       items.append(newItem)
   }
   let welcome = Welcome(items: items)
   // Now you can encode and send welcome
}

【讨论】:

  • 在你说的最后://现在你可以编码和发送欢迎,我输入了,Presenter.sendSmsForAllTheMembers(AptId: aptId, data: welcome),它返回一个错误说:无法转换'welcome' 类型的值到预期的参数类型 '[String : Int]'
  • 看起来该函数需要字典。使用Codable,您只需将Welcome 实例传递给JSONEncoder 即可获得JSON Data。你需要重构你的代码来处理这个问题。
  • 我应该更改这部分吗: var parameterEncoding: ParameterEncoding { return URLEncoding.default }
  • 我不知道。我不知道您的 Sendsms 功能在该字典中想要什么。最好创建接受特定对象或结构的函数而不是通用字典,因为它可以使您的接口更明确地定义和自我记录。
  • 我正在使用 alamofire 和 moya,这是我用于 moya 的代码
【解决方案2】:

好的,据我所知,你想做什么,

1-给出switch标签,

里面

    func tableView(_ tableView: UITableView, 
      cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      switch.tag = indexPath.row
      switch.addTarget(self, action: #selector(onSwitchValueChanged), for: .touchUpInside)

}

而在Switch的didChange方法中,

    func onSwitchValueChanged(_ switch: UISwitch) {
       if switch.on {
       selectedArray.append(dataArray[switch.tag])
    } esle {
      selectedArray.remove(at: switch.tag)
}

【讨论】:

  • 我想我没有清楚地解释我在寻找什么。我调用的第一个方法是一个 get 方法,它为我提供了我在表中呈现的数据。用户只能更改开关。用户可以随意更改它,直到他/她按下按钮!当按下按钮时,我需要获取每个单元格后面的隐藏数据并将它们存储在我的结构中并将其发送到具有另一种方法的 API。当用户按下按钮时,我需要来自每个打开了开关的单元格的 2 个数据
  • 这可以给你一个想法,当你得到 selectedArray,你可以做任何你想做的事情这段代码给你什么用户选择,“selectedArray”是你在顶部定义的一个空数组并给它相同对象的数据类型,当用户单击按钮时,您只需获取此数组并获取其数据非常简单
  • 如果您愿意,我可以编辑和解释更多内容,完成后请批准我的回答,谢谢
  • 你的意思是如果用户随机更改开关自动添加和删除数组中的项目?
  • 我应该如何使用此代码获取 unitNo 和 personId?
【解决方案3】:

SmsCell

var switchHandler: ((Bool)->Void)?

@IBAction func switchChanged(_ sender: UISwitch) {
    self.switchHandler?(sender.isOn)
}

视图控制器

var selectedCells = Set<IndexPath>()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "SmsCell") as! SmsTableViewCell
    let cellData = self.data![indexPath.section]
    let contact = cellData.contacts[indexPath.row]
    cell.PhonNumberLbl.text = contact.phoneNumber
    cell.NameLbl.text = contact.name
    cell.selectedTF.isOn = self.selectedCells.contains(indexPath)
    cell.switchHandler = { (switchState) in
        if switchState {
            self.selectedCells.insert(indexPath)
        } else {
            self.selectedCells.remove(indexPath)
        }
    }
    return cell
}


struct Itemm: Codable {
    let unitNo: Int
    let personId: Int
}

struct Welcome: Codable {
    var items:[Itemm]
}

视图控制器

  @IBAction func sendButtonTapped(_ sender: UIButton) {

      var items = [[String:Int]]()
for indexPath in self.selectedCells {
    let data = self.data![indexPath.section]
    let contact = data.contacts[indexPath.row]
    items.append(["Number" : data.unitNo, "ID" : contact!.id])
}
let welcome = ["items" : items]
print(welcome)
Presenter.sendSmsForAllTheMembers(AptId: aptId, data: welcome)
    }

最终的答案是一些人在这里给我的答案和我自己找到的一些答案的组合

【讨论】:

    【解决方案4】:

    您可以在开关功能时更新您的模型对象,也可以将开关标签作为cell.indexpath

    像这样更新模型对象 Ex :-

    if switch == on {
    
     items[switch_tag].unitNo =0 
    
    } else {
    
      items[switch_tag].unitNo =1 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-09
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      相关资源
      最近更新 更多