tableView.reloadData()不起作用,可能没有在主线程

时间:2018-03-06 00:00:08

标签: swift uitableview

我有一个包含3个部分的tableView。现在我只是真正测试第一部分是Add Friends。我有一个搜索栏,当我输入文本时,我会搜索用户是否存在并重新加载表格。

根据我的理解,我尝试将搜索任务添加到OperationQueue中,以便在用户编辑搜索字段时我可以取消它。

我确认用户可以被搜索,我的电话正在返回该用户。但是,当我将用户添加到我的addFriendsSection并刷新我的tableView时,什么也没发生。我期待使用搜索到的用户的用户名添加新单元格。

class AddFriendTableViewController: UITableViewController, UISearchDisplayDelegate, UISearchBarDelegate {

    private var sectionTitles = ["Add Friends", "Added Me", "My Followers"]

    private var addFriendsSection = [User]()
    private var addedMeSection    = [FollowRequest]()
    private var myFriendsSection  = [Follower]()

    private var sections: [[Any]]!

    private var searchUserBackgroundQueue = OperationQueue()

    @IBOutlet weak var searchBar: UISearchBar!

    override func viewDidLoad() {
        super.viewDidLoad()

        sections = [
            addFriendsSection,
            addedMeSection,
            myFriendsSection
        ]

        searchBar.isTranslucent = true
        searchBar.alpha = 1
        searchBar.backgroundImage = UIImage()
        searchBar.barTintColor = .clear
        searchBar.delegate = self
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].count
    }

    // User edits the search bar
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchUserBackgroundQueue.cancelAllOperations()

        addFriendsSection = []
        tableView.reloadData()

        if searchText.count >= SignupUsernameViewController.minimumUsernameLength {

            searchUserBackgroundQueue.addOperation {
                UserHandler.shared.exists(username: searchText) { (error, user) in
                    if let user = user {

                        // ATTEMPTING TO RELOAD HERE
                        DispatchQueue.main.async {
                            self.addFriendsSection.append(user)
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    }

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

        switch(sectionTitles[indexPath.section]) {
        case sectionTitles[0]:
            let cell = tableView.dequeueReusableCell(withIdentifier: "addFriendsCell", for: indexPath) as! AddFriendsCell

            cell.usernameLabel.text = addFriendsSection[indexPath.row].username

            return cell
        case sectionTitles[1]:
            let cell = tableView.dequeueReusableCell(withIdentifier: "addedMeCell", for: indexPath)

            return cell
        case sectionTitles[2]:
            let cell = tableView.dequeueReusableCell(withIdentifier: "myFollowersCell", for: indexPath)

            return cell
        default:
            print("AddFriendsTableViewController cellForRowAt error!")
        }

        var cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
        return cell
    }

}

1 个答案:

答案 0 :(得分:1)

问题是您将新朋友存储在self.addFriendsSection数组中,但UITableViewDataSource方法(如tableView(_:numberOfRowsInSection:)}访问sections[section].count数组。 当您习惯于Objective-C,Java,C#等时,这可以正常工作,但在Swift中,数组是值类型复制值。

因此,当您初始化sections数组(在viewDidLoad中)时,这将复制 addFriendsSection数组中的值(最初为空) ,numberOfRows...将返回0。然后,在搜索之后,您更新addFriendsSection,但这不会影响sections数组的内容,因此numberOfRows仍会返回0

最快的解决方案是:

  • 删除sections数组,只使用三个不同的数组
  • 或删除三个不同的数组,仅适用于sections

请参阅第一个提案的丑陋快速且肮脏的代码 - 您必须使用枚举,常量或其他内容更好地执行此操作:< / p>

override func numberOfSections(in tableView: UITableView) -> Int {
    return 3
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
        case 0: return addFriendsSection.count
        case 1: return addedMeSection.count
        case 2: return myFriendsSection.count
        default: return 0
    }
}