【问题标题】:Selected row from each section of UITableView ( Multiple Selection )从 UITableView 的每个部分中选择的行(多选)
【发布时间】:2018-09-04 09:07:59
【问题描述】:

我用过tableview(分组)。

所以我需要从 UITableviewSection 的每个部分中选择一行。

因此,我有 tableview 和一个提交按钮。所以我需要检查何时单击提交按钮,我需要检查我是否从每个部分中选择了一行,如果没有,则显示警报未选择段号。如何查看?

这是我的数据。

{
    "data":[
              {
               "question": "Gender",
               "options": ["Male","Female"]
              },
              {
               "question": "How old are you",
               "options": ["Under 18","Age 18 to 24","Age 25 to 40","Age 41 to 60","Above 60"]
              },
              {
               "question": "I am filling the Questionnaire for?",
               "options": ["Myself","Mychild","Partner","Others"]
              }
            ]


}

问题模型:-

class QuestionListModel: NSObject {
     var selected = false

    var dataListArray33:[NH_OptionsModel] = []


    var id:Int!
    var question:String!
    var buttontype:String!
    var options:[String]?
    var v:String?

      var optionsModelArray:[OptionsModel] = []
    init(dictionary :JSONDictionary) {

        guard   let question = dictionary["question"] as? String,
            let typebutton = dictionary["button_type"] as? String,

                let id = dictionary["id"] as? Int
             else {
                return

        }



        if let options = dictionary["options"] as? [String]{
            print(options)

           print(options)


            for values in options{

                print(values)

                let optionmodel = OptionsModel(values: values)
                self.optionsModelArray.append(optionmodel)

            }


        }


        self.buttontype = typebutton
        self.question = question
        self.id = id
    //   print(self.dataListArray33)
                   }

}

optionModel:-

class OptionsModel: NSObject {

    var isSelected:Bool? = false

  var v:String?
        var values:String?



     init(values:String) {

           self.values = values
           print( self.values)

        }

视图模型:-

     func numberOfSections(tableView: UITableView) -> Int{
            print((datasourceModel.dataListArray?.count)!)
            return (datasourceModel.dataListArray?.count)!
        }

        func titleForHeaderInSection(atsection section: Int) -> NH_QuestionListModel {
            return datasourceModel.dataListArray![section]
        }

        func numberOfRowsIn(section:Int) -> Int {

            print( datasourceModel.dataListArray?[section].optionsModelArray.count ?? 0)
            return datasourceModel.dataListArray?[section].optionsModelArray.count ?? 0
            // return self.questionsModelArray?[section].optionsModelArray.count ?? 0
        }

        func datafordisplay(atindex indexPath: IndexPath) -> NH_OptionsModel{

            print(datasourceModel.dataListArray![indexPath.section].optionsModelArray[indexPath.row])

            return datasourceModel.dataListArray![indexPath.section].optionsModelArray[indexPath.row]

        }
 func question(answer:String)  {
        print(questions)
        questions.append(answer)
        print(questions )



    }

    func questionlist(answer:String)  {
        print( questionlist )
        questionlist.append(answer)
        print( questionlist )



    }
    func answer(answer:String)  {
      answers.append(answer)
               print(answers)



    }

最后是 viewController:-

func numberOfSections(in tableView: UITableView) -> Int {
        return questionViewModel.numberOfSections(tableView: tableView)
    }


    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {


        let identifier = "HeaderCell"

        var headercell: questionheader! = tableView.dequeueReusableCell(withIdentifier: identifier) as? questionheader

        if headercell == nil {
            tableView.register(UINib(nibName: "questionheader", bundle: nil), forCellReuseIdentifier: identifier)
            headercell = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_questionheader
        }

        headercell.setReviewData(reviews:questionViewModel.titleForHeaderInSection(atsection:section))




        return headercell
    }



    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

        return 150

    }



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return questionViewModel.numberOfRowsIn(section: section)
    }


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


        let identifier = "Cell"
        var cell: QuestionListCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? QuestionListCell

        if cell == nil {
            tableView.register(UINib(nibName: "QuestionListCell", bundle: nil), forCellReuseIdentifier: identifier)
            cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_QuestionListCell
        }
        cell.contentView.backgroundColor = UIColor.clear


        let questionsModel = questionViewModel.titleForHeaderInSection(atsection:indexPath.section)
        print(questionsModel.buttontype)

        questionViewModel.button = questionsModel.buttontype


        cell.setOptions(Options1: questionViewModel.datafordisplay(atindex: indexPath))

         print("Section \(indexPath.section), Row : \(indexPath.row)")


        return cell

    }





    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){


        print("Section \(indexPath.section), Row : \(indexPath.row)")


        let cell = tableview.cellForRow(at: indexPath) as? NH_QuestionListCell

        let model = questionViewModel.datafordisplay(atindex: indexPath)

        print(model.isSelected)


        cell?.setOptions(OptionsSelected:questionViewModel.datafordisplay(atindex: indexPath))
        print(model.isSelected)
        questionViewModel.isselected = model.isSelected!



        let section = indexPath.section
        let index = indexPath.row
        print(section)
        print(index)



        if !questionViewModel.selectedIndexPaths.contains(indexPath) {

            questionViewModel.selectedIndexPaths.append(indexPath)
            print(questionViewModel.selectedIndexPaths.append(indexPath))


            let questionModel = questionViewModel.titleForHeaderInSection(atsection: section)
            print(questionModel.question)


            questionViewModel.question = questionModel.question
            questionViewModel.questionlist(answer: questionViewModel.question!)


            let cell = tableview.cellForRow(at: indexPath) as? NH_QuestionListCell

            let model = questionViewModel.datafordisplay(atindex: indexPath)
            print(model.values)

            questionViewModel.answer(answer: model.values!)

            let value: Int = questionModel.id
                let string = String(describing: value)
                //let x: Int? = Int(model.id)

            questionViewModel.question_id = string
            questionViewModel.question(answer: questionViewModel.question_id!)

            print(questionModel.id)

            // append the selected index paths
        }       //  if indexPath.section == section {
       //     questionViewModel.indexPath(indexPaths: index)
       // }


            }

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {




        if let index = questionViewModel.selectedIndexPaths.index(of: indexPath) {
            print(index)
            questionViewModel.selectedIndexPaths.remove(at: index)
        }



}

据此,我得到了输出。 但我在视图控制器中有按钮操作。

@IBAction func forward(_ sender: AnyObject) {
}

在此按钮操作中,我需要检查是否从每个部分中选择了一行。如果不显示警报。如何做

我目前的 didselect 方法:-

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
 let cell = tableview.cellForRow(at: indexPath) as? NH_QuestionListCell

            let model = questionViewModel.datafordisplay(atindex: indexPath)

            print(model.isSelected)


            cell?.setOptions(OptionsSelected:questionViewModel.datafordisplay(atindex: indexPath))
            print(model.isSelected)
            questionViewModel.isselected = model.isSelected!



            let section = indexPath.section
            let index = indexPath.row
            print(section)
            print(index)


            if !questionViewModel.selectedIndexPaths.contains(indexPath) {

                questionViewModel.selectedIndexPaths.append(indexPath)
                print(questionViewModel.selectedIndexPaths.append(indexPath))


                let questionModel = questionViewModel.titleForHeaderInSection(atsection: section)
                print(questionModel.question)


                questionViewModel.question = questionModel.question
                questionViewModel.questionlist(answer: questionViewModel.question!)


                let cell = tableview.cellForRow(at: indexPath) as? NH_QuestionListCell

                let model = questionViewModel.datafordisplay(atindex: indexPath)
                print(model.values)

                questionViewModel.answer(answer: model.values!)

                let value: Int = questionModel.id
                    let string = String(describing: value)
                    //let x: Int? = Int(model.id)

                questionViewModel.question_id = string
                questionViewModel.question(answer: questionViewModel.question_id!)

                print(questionModel.id)

                          }

我有 3 个数组 根据这个didselect方法:-

例如:-对于第 1 部分:-我选择了第一行,因此数据如下所示。

questionlist:["How r u?"]
answelist:["fine"]

但假设我认为我需要第二个索引路径,所以我需要从数组中删除以前附加的数据并附加当前数据。如下:

questionlist:["How r u?"]
answelist:["not well"]

接下来是第 2 节:我选择了第一个 indexpath.row 数据。然后该数据是追加的。所以我需要得到如下:-

 questionlist:["How r u?","Gender"]
    answelist:["not well","Male"]

在这里选择我认为我需要第二个选项,然后从数组中删除添加的 indexpath.row 数据并显示为:-

 questionlist:["How r u?","Gender"]
        answelist:["not well","Female"]

这样怎么设置?

【问题讨论】:

  • 检查 didSelectRow 哪个选项在哪个部分被按下,并将选定的选项单独保存为属性。然后你只需要验证属性是否不为零。
  • @FabioBerger 我已经更新了我当前的代码状态。在这个按钮操作中应该写什么?如何验证?
  • @FabioBerger 如何实现?
  • 在属性中保存性别、年龄等选项。向前检查是否没有属性为空
  • @FabioBerger 我已更新

标签: ios swift uitableview


【解决方案1】:

您可以根据选择更新您的模型,例如

"data":[
              {
              "question": "Gender",
              "options": ["Male","Female"],
              "optionSelected": "Male"

              }
              ]

在提交时,检查选择的数据

【讨论】:

    【解决方案2】:

    表格视图具有获取选定索引路径的属性。您可以为此使用所有本机组件。您需要的是取消选择索引路径中的某个项目,该项目已在某个部分中选择。您还只需检查所选索引路径的数量是否与数据源中的数组数量相同。

    检查如下:

    var dataSource: [[Any]]!
    var tableView: UITableView!
    
    func didSelectRowAt(_ indexPath: IndexPath) {
        guard let selectedPaths = tableView.indexPathsForSelectedRows else { return } // We need to have selected paths
        guard selectedPaths.contains(indexPath) == false else { return } // The same cell being selected
    
        let previouslySelectedCellIndexPaths: [IndexPath] = selectedPaths.filter { $0.section == indexPath.section && $0 != indexPath } // Getting all selected index paths within this section
        previouslySelectedCellIndexPaths.forEach { tableView.deselectRow(at: $0, animated: true) } // Deselect waht was previously selected
    }
    
    /// Will return array of selected objects only if all sections have a selected index
    ///
    /// - Returns: A result array
    func getSelectionData() -> [Any]? {
        guard let selectedPaths = tableView.indexPathsForSelectedRows else { return nil } // We need to have selected paths
        guard selectedPaths.count == dataSource.count else { return nil } // This should prevent missing selections assuming all index paths are unique in sections
        return selectedPaths.map { dataSource[$0.section][$0.row] } // Map selected index paths back to objects
    }
    

    我尝试使用一种最少的代码来显示所有这些。所有内容均已注释,因此您可以逐行查看发生的情况。

    您可能想检查是否所有部分都是唯一的第二种方法,但如果始终使用第一种方法,则不需要。

    【讨论】:

    • didSelectRowAt 函数应该在哪里调用?
    • @clydececiljohn 在委托方法tableView(_ tableView: UITableView, didSelectRowAt 中的任何位置。您甚至可以将这个方法的内容粘贴到其中,但注意不要与您自己的代码冲突。
    【解决方案3】:

    您可以将选定的 indexPath 存储在数组中。 OnClick 提交只是循环遍历数组并检查每个部分中至少一个元素。

    仅供参考:indexPath 也包含部分信息。

    声明一个可变数组并在 viewDidLoad 中分配。

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
            [anArray addObject:indexPath];
    
    }
    

    在提交动作后,您可以根据自己的要求即兴创作

    -(void)onSubmitAction{
         [anArray addObject:indexPath];
         NSMutableArray *countOfSection=[[NSMutableArray alloc]init];
        for (NSIndexPath*indexPath in anArray ) {
          if(![anArray containsObject:indexPath.section])
            [countOfSection addObject:indexPath.section];
          }
          if(countOfSection.count == self.tableview.numberOfSections){
        //write your code
          }else{
        // show alert
       }
    
      }
    

    【讨论】:

    • 我已经在目标 C 中给出了示例代码,swift 也会一样。如果你仍然没有得到这个,我也会写 swift sn-p。谢谢
    • 这里是 2 的部分。但是部分计数基于 url 中的数据。所以怎么做
    • 您可以将模型保存在数组中并检查属性以从每个部分中找到至少任何一个被选中,或者您可以按照我的建议进行操作。我已经对您的节数问题进行了编辑
    【解决方案4】:

    第一步:创建全局变量

    var selectedIndexPaths = [IndexPath]() 
    

    第二步:添加 UITableView 属性

    tableView.allowsMultipleSelection = true
    

    第 3 步:实现委托方法

    //On Selection
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)      {
    
    
            let selectedIndexPathAtCurrentSection = selectedIndexPaths.filter({ $0.section == indexPath.section})
    
            for indexPath in selectedIndexPathAtCurrentSection {
                tableView.deselectRow(at: indexPath, animated: true)
                if let indexOf = selectedIndexPaths.index(of: indexPath) {
                    selectedIndexPaths.remove(at: indexOf)
                }
            }
            selectedIndexPaths.append(indexPath)
    
    
    }
    // On DeSelection
     func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    
        if let index = selectedIndexPaths.index(of: indexPath) {
            selectedIndexPaths.remove(at: index)
        }
    }
    

    第 4 步:使用部分获取选定的 IndexPaths

    @IBAction func forward(sender:Any){
    
          let totalSections = questionViewModel.numberOfSections(tableView: tableView)
    
    
           for section in 0..<totalSections {
    
            if (selectedIndexPaths.filter({ $0.section == section}).count >= 1) {
                continue
            } else {
    
                // Show alert
                print("Please select item at",(section))
                return
            }
        }
    
    }
    

    【讨论】:

    • 这里显示对成员tableview的模糊引用(_viewforheaderInSection)如何解决
    • 我有一个问题。我已经更新了视图模型中的一些函数并更新了 ViewController 中的 didselect 方法。请检查。所以根据你的代码。代码很好。
    • 但我需要 3 个数组。在选择单元格时,我需要将数据附加到数组中。我在 didselect 方法中提到。但在这里我应该只能为每个单元格选择一个单元格。例如:-问题1-在问题1中,我从选项中选择了一个选项并附加了数据。但是虽然我认为我不需要第一个选项,但我需要选择第二个选项。所以我点击了第二个选项。所以根据我这里的代码:-2 数据将进入。但我需要删除以前添加的列表,只需要当前选择的数据。怎么办?
    • 哦,您的意思是说应该从一个部分中只选择一个单元格,如果用户想从同一部分中选择另一个问题(单元格),那么您应该取消选择您之前选择的第一个单元格?跨度>
    • 哦是的。怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 2016-04-06
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多