Swift 3/4 - 仅在所需的tableView单元格中填充数据

时间:2018-04-26 07:46:12

标签: arrays swift uitableview dictionary indexoutofboundsexception

我用动态JSON数据填充我的tableView。我设计了自定义tableviewCell,我隐藏了一个视图,只在数据出现时显示。首先,我在tableView中显示所有员工姓名,稍后当他们被分配任何项目时,我必须在DetailsView中显示项目详细信息,如下所示。 enter image description here

这里我在EmployeeList的employeeIds的forLoop中调用了projectDetails api。 我将项目详细信息存储在一个数组中,并通过 cellForRow 中的projectListArray[indexPath.row]将值分配给行。但问题是,当某些员工没有分配任何项目时,我会得到索引超出范围错误。 ExpandableCell将继续崩溃。希望我到此为止。

因此,只有已分配项目的员工才会显示ExpandableCell已展开,而对于其他人,该单元格将被折叠。

    public func getEmployeesList(request : EmployeesListRequest) {      // api call to get Employees List

        // if EmployeeListArray is not till and if response is SUCCESS, give ProjectDetails api call 

     if response.isSuccess() {
         for beds in array {
            self.getProjectDetails(request: self.projectDetailsRequest)
            //refresh TableView 
        }
    }                     
}

public func getProjectDetails(request : ProjectDetailsRequest) {

    if Network.response(response: response, errorMsg: nil) {
        let object = response.obj as? ProjectDetails                 
            if response.isSuccess() {
                if response.obj != nil {
                    self.projectDetailsArray.append(object!)
                    self.projectEmployeeIdArray.append(object.employeeId!)
                 }else{
                     print(“Project Object is nil\n")
                }
                }
            }
    }

// In cellForRowAt indexPath
// Displayed Employee names in NamesView now want to display project details
var expandedRows = Set<IndexPath>()
for id in projectEmployeeIdArray {
            if employeeId == id {
                cell.projectDetailsView.isHidden = false
                expandedRows.insert(indexPath)

                if !projectDetailsArray.isEmpty{
                        let sortedData = projectDetailsArray.sorted(by:{$0.employeeId < $1.employeeId})   //since the dictionary was not sorted. //Error if some ids nil
                    let details = sortedData[indexPath.row]             //Error because some employees do not project assigned.

                    cell.projectLabel.text = details.projectName!

                }else{                                        
                    expandedRows.remove(indexPath)
            }
        }
    }

我还尝试了projectDetailsArray[safe: indexPath.row],但未能分配项目项目详细信息。如果索引0和2具有项目详细信息,则它将为索引2提供nil数据。

所需输出: enter image description here

1 个答案:

答案 0 :(得分:0)

我强烈建议您创建一个数据模型,例如

struct Employee {
    var id = ""
    var name = ""
    var projects = [Project]()
}

struct Project {
    var name = ""
}

var model = [Employee]()

如果您有这个,您需要以您喜欢的排序方式将JSON-Response转换为Employee / Project Model。这只需要进行一次而不是每次cellForRowAt indexPath调用

UITableViewDataSource函数的实现非常简单:

  • numberOfSections(in:)中返回model
  • 中的员工人数
  • tableView(_:numberOfRowsInSection:)中,获取给定部分的员工,并返回其项目的计数
  • tableView(_:titleForHeaderInSection:)中,获取给定部分的员工并返回其名称(或者您希望在此处显示的任何内容)
  • tableView(_:cellForRowAt:)中,获取给定indexPath.section的员工,根据indexPath.row获取该员工的项目并配置单元格