【问题标题】:Swift: Update/replace an object in array of objectsSwift:更新/替换对象数组中的对象
【发布时间】:2020-11-16 11:16:12
【问题描述】:

我遇到了一个实际上看起来更简单的问题。

  1. 我有一个 preferenceSet 类型的 Preference 数组,我使用它填充 tableView 部分的行。 (即在我的 tableView 中,每个部分都有一组首选项)。
  2. tableView 的部分可以折叠/展开。 (当用户点击部分标题时会发生切换)

现在,出于偏好,当值发生变化时(truefalsefalsetrue),我进行 API 调用,当它是 success 时,我更新回来我的preferenceSet 和新的updatedPrefSet。这在一个扩展部分的情况下非常有效。现在的问题是当有多个扩展部分时。

我在下面的操作是为了过滤掉应该根据updatedPrefSet 更新的首选项。 代码:

func expandOrCollapseCategory(sender: CategoryGestureRecoginzer, preferenceSet: [CustomerPreference]) {
    let updatedPrefSet = preferenceSet.filter({$0.categoryCode == sender.categoryCode})                      
                
    for i in 0..<self.preferenceSet.filter({$0.categoryCode == sender.categoryCode}).count {
                    if self.preferenceSet[i].categoryCode == sender.categoryCode {
                        self.preferenceSet[i].code = updatedPrefSet[i].code
                        self.preferenceSet[i].dataType = updatedPrefSet[i].dataType
                        self.preferenceSet[i].description = updatedPrefSet[i].description
                        self.preferenceSet[i].name = updatedPrefSet[i].name
                        self.preferenceSet[i].preferenceValues = updatedPrefSet[i].preferenceValues
                        self.preferenceSet[i].value = updatedPrefSet[i].value
                    }
                }
                
                let sectionNumber = self.preferenceCategories?.firstIndex(where: {$0.code == sender.categoryCode})
                
                self.preferencesTableView.reloadSections([sectionNumber!], with: .fade)

}

这里,categoryCode 是我用来过滤对象的属性。我将收到的updatedPrefSetcategoryCode(在sender 的帮助下)与self.preferenceSetcategoryCode 进行比较,并尝试仅替换我的self.preferenceSet 中的那组对象。

此外,这也是我用来展开/折叠两者之间没有冲突的部分的相同方法。

我验证了我的updatedPrefSet,它是从服务调用中返回的,它始终是正确的! (从邮递员验证)。问题仅在于更新我的self.preferenceSet。我不确定循环或更新对象时哪里出错了。

video link here 中,第一部分中的值更改运行良好且符合预期。第二部分不更新预期值,第三部分根本不更新任何内容。即使我每次都获得成功的更新对象响应 (updatedPrefSet)。

更新 1: 我更新了我的代码如下(感谢@Robert,确认您的评论相同)。但行为仍然相同。首先展开的部分的值更改效果很好。对于任何其他部分更改,更新的值不会反映。 :|

for i in 0..<self.preferenceSet.filter({$0.categoryCode == sender.categoryCode}).count {
                
                if self.preferenceSet[i].categoryCode == sender.categoryCode {
                    self.preferenceSet.filter({$0.categoryCode == sender.categoryCode})[i].code = updatedPrefSet[i].code
                    self.preferenceSet.filter({$0.categoryCode == sender.categoryCode})[i].dataType = updatedPrefSet[i].dataType
                    self.preferenceSet.filter({$0.categoryCode == sender.categoryCode})[i].description = updatedPrefSet[i].description
                    self.preferenceSet.filter({$0.categoryCode == sender.categoryCode})[i].name = updatedPrefSet[i].name
                    self.preferenceSet.filter({$0.categoryCode == sender.categoryCode})[i].preferenceValues = updatedPrefSet[i].preferenceValues
                    self.preferenceSet.filter({$0.categoryCode == sender.categoryCode})[i].value = updatedPrefSet[i].value
                }
            }

这是我的**numberOfRows****cellForRowAt**

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let preferenceCategories = self.preferenceCategories else {
                return UITableViewCell()
            }
            
            let categoryCode = preferenceCategories[indexPath.section].code
            
            let filteredPreferenceSet = self.preferenceSet.filter({$0.categoryCode == categoryCode})
            
            if let preferenceDataType = filteredPreferenceSet[indexPath.row].dataType {
                
                switch preferenceDataType {
                case "BOOLEAN":
                    let cell = self.preferencesTableView.dequeueReusableCell(withIdentifier: "CustPrefSetCell", for: indexPath) as! CustPrefSetCell
                    
                    cell.categoryCode = categoryCode!
                    cell.preferenceName.text = filteredPreferenceSet[indexPath.row].name
                    cell.preferenceDescription.text = filteredPreferenceSet[indexPath.row].description
                    
                    cell.switchDelegate = self
                    
                    let propertyValue = ((filteredPreferenceSet[indexPath.row].value ?? "false") as NSString).boolValue
                    
                    propertyValue ? cell.preferenceSwitch.setOn(true, animated: true) : cell.preferenceSwitch.setOn(false, animated: true)
                    
                    cell.preferenceCode = filteredPreferenceSet[indexPath.row].code
                    
                    if indexPath.row == filteredPreferenceSet.count - 1 {
                        cell.customSeparator.isHidden = true
                    }
                    else {
                        cell.customSeparator.isHidden = false
                    }
                    
                    return cell
                    
                    
                case "MULTISELECT":
                    let multiSelectCell = self.preferencesTableView.dequeueReusableCell(withIdentifier: "CustPrefMultiSelectTableViewCell", for: indexPath) as! CustPrefMultiSelectTableViewCell
                    
                    multiSelectCell.configureCell(of: categoryCode!, with: filteredPreferenceSet[indexPath.row].preferenceValues!)
                    
                    multiSelectCell.preferenceTitle.text = filteredPreferenceSet[indexPath.row].name
                    
                    if filteredPreferenceSet[indexPath.row].description != nil {
                        multiSelectCell.preferenceDescription.text = filteredPreferenceSet[indexPath.row].description
                    }
                    else {
                        multiSelectCell.preferenceDescription.text = ""
                        multiSelectCell.titleBottomConstraint.constant = 0
                        multiSelectCell.descriptionBottomConstraint.constant = 0
                    }
                    
                    multiSelectCell.multiSelectSwitchDelegate = self
                    
                    multiSelectCell.setNeedsLayout()
                    multiSelectCell.layoutIfNeeded()

                    return multiSelectCell
                    
                case "SINGLESELECT":
                    let singleSelectCell = self.preferencesTableView.dequeueReusableCell(withIdentifier: "CustPrefSingleSelectTableViewCell", for: indexPath) as! CustPrefSingleSelectTableViewCell
                    
                    singleSelectCell.configureCell(of: categoryCode!, with: filteredPreferenceSet[indexPath.row].preferenceValues!, and: filteredPreferenceSet[indexPath.row].code!, withSelectedDefaultValue: filteredPreferenceSet[indexPath.row].value ?? "")
                    
                    singleSelectCell.preferenceTitle.text = filteredPreferenceSet[indexPath.row].name
                    
                    
                    if filteredPreferenceSet[indexPath.row].description != nil {
                        singleSelectCell.preferenceDescription.text = filteredPreferenceSet[indexPath.row].description
                    }
                    else {
                        singleSelectCell.preferenceDescription.text = ""
                        singleSelectCell.titleBottomConstraint.constant = 0
                        singleSelectCell.descriptionBottomConstraint.constant = 0
                    }
                    
                    singleSelectCell.radioDelegate = self
                    
                    singleSelectCell.setNeedsLayout()
                    singleSelectCell.layoutIfNeeded()
                    
                    return singleSelectCell
                    
                default:
                    return UITableViewCell()
                    
                }
            }
            else {
                return UITableViewCell()
            }
}

【问题讨论】:

  • 您是否为每个 CustomerPreference 值设置了唯一标识符?您的问题是您正在使用i 来索引updatedPrefSetself.preferenceSet
  • 是的,我将代码更改为使用 categoryCode 作为唯一标识符。现在我的 cellForRowAt 出现问题...我将编辑我的问题

标签: ios arrays swift uitableview


【解决方案1】:

花了一些时间后,我发现了用 updatedPrefSet 更新 self.preferenceSet 的逻辑被破坏的问题。我删除了 if 比较并遍历 self.preferenceSet 中的所有元素。最终的工作代码如下 -

func expandOrCollapseCategory(sender: CategoryGestureRecoginzer, preferenceSet: [CustomerPreference]) {
    let updatedPrefSet = preferenceSet.filter({$0.categoryCode == sender.categoryCode})                      
                
    for i in 0..<self.preferenceSet.filter({$0.categoryCode == sender.categoryCode}).count {
                    
                        self.preferenceSet[i].code = updatedPrefSet[i].code
                        self.preferenceSet[i].dataType = updatedPrefSet[i].dataType
                        self.preferenceSet[i].description = updatedPrefSet[i].description
                        self.preferenceSet[i].name = updatedPrefSet[i].name
                        self.preferenceSet[i].preferenceValues = updatedPrefSet[i].preferenceValues
                        self.preferenceSet[i].value = updatedPrefSet[i].value
                    
                }
                
                let sectionNumber = self.preferenceCategories?.firstIndex(where: {$0.code == sender.categoryCode})
                
                self.preferencesTableView.reloadSections([sectionNumber!], with: .fade)

}

【讨论】:

    猜你喜欢
    • 2016-10-01
    • 2018-10-03
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2018-06-30
    • 2020-01-16
    • 2020-11-08
    • 1970-01-01
    相关资源
    最近更新 更多