xcode Swift 3 tableView 未在 reloadData() 上更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42592375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 09:49:07  来源:igfitidea点击:

Swift 3 tableView not updating on reloadData()

iosswiftxcodeuitableviewcheckmark

提问by Chris Bell

I am building a master detail app. I have a sections view controller (VC) which is a child of master VC. Clicking on rows in the sections VC brings up different detail VCs where users complete required information. Once the information in a detail VC is completed I would like to have a checkmark display in the relevant section VC row. FYI selectedProject is a core data object.

我正在构建一个主细节应用程序。我有一个部分视图控制器 (VC),它是主 VC 的子项。单击 VC 部分中的行会显示不同的详细 VC,用户可以在其中完成所需的信息。完成详细 VC 中的信息后,我希望在相关部分 VC 行中显示复选标记。仅供参考 selectedProject 是一个核心数据对象。

I call a notification in the detail VC viewWillDisappear to refresh the sections VC.

我在详细 VC viewWillDisappear 中调用通知以刷新 VC 部分。

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let detailCase: String = selectedProject!.section![indexPath.row]
    configureCell(cell, withSectionName: detailCase)
    print("location complete is \(selectedProject!.completeLocation)")
    print("electricity complete is \(selectedProject!.completeElectricity)"
    print(cell.textLabel!.text!)
    print(cell.accessoryType.rawValue)
    return cell
}

func configureCell(_ cell: UITableViewCell, withSectionName sectionName: String) {
        switch sectionName {
        case "Project Details" :
            cell.accessoryType = .checkmark
        case "Location" :
            if selectedProject?.completeLocation == true {
                cell.accessoryType = .checkmark
            }
        case "Electricity Use" :
            if selectedProject?.completeElectricity == true {
                cell.accessoryType = .checkmark
            }
        default :
            cell.accessoryType = .none
        }
        cell.textLabel!.text = sectionName
}

func refreshTable(notification: Notification) -> Void {
    print("Notification ran")
    self.tableView.reloadData()
}

Console:

安慰:

Notification ran

通知已运行

location complete is true

位置完整是真的

electricity complete is true

电完成是真的

Project Details

项目详情

3

3

location complete is true

位置完整是真的

electricity complete is true

电完成是真的

Location

地点

3

3

location complete is true

位置完整是真的

electricity complete is true

电完成是真的

Electricity Use

用电

3

3

The 3's = .checkmark

3's = .checkmark

So it appears cellForRowAt knows exactly what it should be doing but then the table is not readily displaying the checkmarks. Instead you either have to click back to the master VC then forward to the sections VC to get the checkmarks displaying, or you have to click different rows in the section VC and the checkmarks will randomly show up.

所以看起来 cellForRowAt 确切地知道它应该做什么,但是表格并不容易显示复选标记。相反,您要么必须单击回到主 VC 然后转发到 VC 部分以显示复选标记,或者您必须单击 VC 部分中的不同行,复选标记将随机显示。

I've tried calling reloadData in dispatchqueue.main.async with no luck. I tried calling reloadData at different points in the process again without success. I've tried calling tableView.beginUpdates/.endUpdates and reloadSectionData, again without success to get the checkmarks to display.

我试过在 dispatchqueue.main.async 中调用 reloadData ,但没有成功。我再次尝试在过程中的不同点调用 reloadData ,但没有成功。我试过调用 tableView.beginUpdates/.endUpdates 和 reloadSectionData,再次没有成功显示复选标记。

If I programmatically prompt section VC viewWilDisappear and viewWillAppear in succession, the checkmarks will appear once a different row in sections VC is selected. it "seems" like reloadData() isn't prompting a complete reload of the tableView.

如果我以编程方式连续提示部分 VC viewWilDisappear 和 viewWillAppear,则一旦选择了部分 VC 中的不同行,就会出现复选标记。它“似乎”像 reloadData() 没有提示完全重新加载 tableView。

FYI accessory item is set to .none in the storyboard.

仅供参考的配件项目在情节提要中设置为 .none。

回答by dylanthelion

UI updates need to be called on the main queue. Try this:

需要在主队列上调用 UI 更新。尝试这个:

DispatchQueue.main.async {
    self.tableView.reloadData()
}

回答by Matthew

This fixed it for me. Hope it helps :)

这为我修好了。希望能帮助到你 :)

 DispatchQueue.main.async {
            self.tableView.reloadData()
            self.tableView.beginUpdates()
            self.tableView.endUpdates()
        }

回答by Chris Bell

Ok so in light of no fixes forthcoming, I went and changed the tableView to static rather than dynamic. I created tableViewCell outlets for all the fixed cells and then added and removed the checkmarks that way.

好吧,鉴于没有修复即将到来,我去将 tableView 更改为静态而不是动态。我为所有固定单元格创建了 tableViewCell 插座,然后以这种方式添加和删除复选标记。

The code for anyone interested:

任何有兴趣的人的代码:

var tableCellArray = [UITableViewCell]()

/*-----------------------------------------------------------*/

// MARK: - Outlets

@IBOutlet weak var projectDetails: UITableViewCell!
@IBOutlet weak var location: UITableViewCell!
@IBOutlet weak var electricityUse: UITableViewCell!

// MARK: - Actions

// MARK: - Default functions

override func viewDidLoad() {
    super.viewDidLoad()
    tableCellArray = [projectDetails, location, electricityUse]
    configureCells()
    NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "refresh"), object: nil, queue: nil, using: refreshTable)
}

// MARK: - Table view data source

func configureCells() {
    var i = 0
    for each in tableCellArray {
        configureCheckmark(each, withIndex: i)
        i = i + 1
    }
}

func configureCheckmark(_ cell: UITableViewCell, withIndex index: Int) {
    var accessoryType: UITableViewCellAccessoryType = .none
    switch index {
        case 0 :
            accessoryType = .checkmark
        case 1 :
            if selectedProject?.completeLocation == true {
                accessoryType = .checkmark
            }
        case 2 :
            if selectedProject?.completeElectricity == true {
                accessoryType = .checkmark
            }
        default :
            accessoryType = .none
        }
    cell.accessoryType = accessoryType
}

func refreshTable(notification: Notification) -> Void {
    configureCells()
    tableView.beginUpdates()
    tableView.endUpdates()
}