无法将单元格添加到 table 视图

Cannot add cell to table view

我是新手,我刚刚在我的应用程序中创建了一个包含所有群组的索引 table 视图“群组搜索”,但遇到了一个问题:当我尝试将一些群组添加到在“我的组”视图中,应该出现一个选定的组,但实际上我从所有组数组中得到了第一个。此外,我无法在“我的群组”中添加多个以相似字母开头的项目。这可能很愚蠢,但我不知道如何解决。谢谢!

import UIKit

final class AllGroupsViewController: UITableViewController {

 var groups = [
     "cats",
     "birds",
     "dogs",
     "books",
     "music",
     "movies",
     "art",
     "science",
     "tech",
     "beauty",
 ]
 var groupSectionTitles = [String]()
 var groupsDictionary = [String: [String]]()

 // MARK: - Lifecycle
 override func viewDidLoad() {
     super.viewDidLoad()
     tableView.register(UINib(
         nibName: "GroupCell",
         bundle: nil),
                        forCellReuseIdentifier: "groupCell")
     
     for group in groups {
         let groupKey = String(group.prefix(1))
         if var groupValues = groupsDictionary[groupKey] {
             groupValues.append(group)
             groupsDictionary[groupKey] = groupValues
         } else {
             groupsDictionary[groupKey] = [group]
         }
     }
     
     
     groupSectionTitles = [String](groupsDictionary.keys)
     groupSectionTitles = groupSectionTitles.sorted(by: { [=11=] <  })
     
 }
 
 // MARK: - Table view data source
 override func numberOfSections(in tableView: UITableView) -> Int {
     return groupSectionTitles.count
 }
 
 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     
     let groupKey = groupSectionTitles[section]
     if let groupValues = groupsDictionary[groupKey] {
         return groupValues.count
     }
     
     return 0
 }
 
 override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
     return groupSectionTitles[section]
 }
 
 override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
     return groupSectionTitles
 }
 
 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     guard
         let cell = tableView.dequeueReusableCell(withIdentifier: "groupCell", for: indexPath) as? GroupCell
     else { return UITableViewCell() }
     
     var currentGroup = groups[indexPath.row]
     
     let groupKey = groupSectionTitles[indexPath.section]
     if let groupValues = groupsDictionary[groupKey] {
         currentGroup = groupValues[indexPath.row]
     }
     
     cell.configure(
         photo: UIImage(systemName: "person.3.fill") ?? UIImage(),
         name: currentGroup)

     return cell
 }

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     defer { tableView.deselectRow(
         at: indexPath,
         animated: true) }
     performSegue(
         withIdentifier: "addGroup",
         sender: nil)
 }

}


import UIKit

final class MyGroupsViewController: UITableViewController {
    var groups = [String]() {
        didSet {
            //
        }
    }
    
    
@IBAction func addGroup(segue: UIStoryboardSegue) {
    guard
        segue.identifier == "addGroup",
        let allGroupsController = segue.source as? AllGroupsViewController,
        let groupIndexPath = allGroupsController.tableView.indexPathForSelectedRow,
        !self.groups.contains(allGroupsController.groups[groupIndexPath.section])
    else { return }
    self.groups.append(allGroupsController.groups[groupIndexPath.section])
    tableView.reloadData()
}
    
    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UINib(
            nibName: "GroupCell",
            bundle: nil),
                           forCellReuseIdentifier: "groupCell")
    }
    
    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        groups.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard
            let cell = tableView.dequeueReusableCell(withIdentifier: "groupCell", for: indexPath) as? GroupCell
        else { return UITableViewCell() }
        
        let currentGroup = groups[indexPath.row]

        cell.configure(
            photo: UIImage(systemName: "person.3.fill") ?? UIImage(),
            name: currentGroup)

        return cell
    }

    override func tableView(
        _ tableView: UITableView,
        commit editingStyle: UITableViewCell.EditingStyle,
        forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            groups.remove(at: indexPath.row)
            tableView.deleteRows(
                at: [indexPath],
                with: .fade)
        }
    }

}


首先这是我理解的目标是:

  1. 有一个名为 MyGroupsViewController 的 UITableViewController,它应该显示用户选择的所有组
  2. 点击 MyGroupsViewController 中的 + 后,用户将被带到另一个名为 AllGroupsViewController 的 UITableViewController,它显示了用户可以加入的所有组
  3. AllGroupsViewController 选择 UITableViewCell 后,您将 unwind 返回到 MyGroupsViewController 显示为用户添加的组

我会说你已经很接近了,我刚刚添加了一些小的东西,希望能让你更接近你的目标。

使用 segue 转换时在 UIViewController 之间传递数据的一种方法是重写一个名为 prepare for segue (Read more about it in the Apple docs)

的函数

1

我要做的第一个更改是将 override prepareForSegue 添加到 MyGroupsViewController class 的末尾,这样我就可以将组数组传递给 AllGroupsViewController

你随便放,我加在你的tableview编辑功能下面

    override func tableView(_ tableView: UITableView,
                            commit editingStyle: UITableViewCell.EditingStyle,
                            forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            groups.remove(at: indexPath.row)
            
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }
    
    // This was added by me
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Check the correct segue identifier and retrieve the destination
        if segue.identifier == "addGroup",
           let allGroupsViewController = segue.destination as? AllGroupsViewController
        {
            // Set the groups variable with data we stored in the
            // user groups array
            allGroupsViewController.userGroups = groups
        }
    }

2

AllGroupsViewController中,我添加了一个用户组数组来存储用户点击的所有组,现有用户的组将在步骤1MyGroupsViewController中发送给它

class AllGroupsViewController: UITableViewController {
    
    var groups = [
        "cats",
        "birds",
        "dogs",
        "books",
        "music",
        "movies",
        "art",
        "science",
        "tech",
        "beauty",
    ]
    
    // I added this. This will save groups the user wants
    var userGroups: [String] = []

3.

然后我对你的 tableView didSelectRowAtIndexPath 函数做了一些小改动来存储用户点击的内容

    override func tableView(_ tableView: UITableView,
                            didSelectRowAt indexPath: IndexPath) {
        defer {
            tableView.deselectRow(at: indexPath, animated: true)
        }
        
        // Added by me: Retrieve the group tapped by the user
        let groupKey = groupSectionTitles[indexPath.section]
        var currentGroup = ""
        if let groupValues = groupsDictionary[groupKey] {
            currentGroup = groupValues[indexPath.row]
        }
        
        // Added by me: Check that this group was not added for the user
        // before to avoid duplicates
        if userGroups.firstIndex(of: currentGroup) == nil {
            userGroups.append(currentGroup)
        }
        
        self.performSegue(withIdentifier: "addGroup", sender: nil)
    }

4

最后,回到 MyGroupsViewController,我稍微更新了您的 addGroup 展开功能,如下所示:

    @IBAction func addGroup(segue: UIStoryboardSegue) {
        guard segue.identifier == "addGroup",
              let allGroupsViewController = segue.source as? AllGroupsViewController
        else { return }
        
        // Added by me. Removed old code and added by me. Just update
        // the groups array with what was selected in AllGroupsViewController
        groups = allGroupsViewController.userGroups
        
        tableView.reloadData()
    }

您将通过向用户添加组来获得此最终结果,没有重复,并且您还可以添加具有相同起始字母的组。

你可以watch the experience here on Youtube

如果我遗漏了什么或没有回答你的问题,请在评论中添加更多信息/问题。