2017-03-04 317 views
3

我正在构建一个主细节应用程序。我有一个章节视图控制器(VC),这是VC大师的孩子。单击VC部分中的行可以提供不同的细节VC,用户可以在其中完成所需的信息。一旦详细信息VC中的信息完成,我想在相关部分VC行中有复选标记显示。 FYI selectedProject是核心数据对象。swift 3 tableView在reloadData上没有更新()

我在详细的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() 
} 

控制台:

通知跑

位置完全是真实的

电力完全是真实的

项目详情

位置完全是真实的

电力完全是真实的

位置

位置完全是真实的

电力完全是真实的

用电量

3的= .checkmark

所以它出现cellForRowAt确切地知道它应该做的事情,但随后该表不容易显示选中标记。相反,您必须单击回主VC,然后转到VC部分才能显示复选标记,或者必须单击VC部分中的不同行,并且复选标记将随机显示。

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

如果我以编程方式提示部分VC viewWilDisappear和viewWillAppear连续,选中部分VC中的不同行后,将出现复选标记。它“似乎”像reloadData()不提示完整的重新加载tableView。

FYI配件项目在故事板中设置为.none。

回答

7

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

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

正确的解决方案! – Mannopson

+0

感谢您的回答。对我提到的问题的底部,我提到我已经尝试DispatchQueue.main.async没有成功。我试着通过通知器来调用它,除非你会建议另一个可能工作的位置。 –

+0

@ChrisBell:在这种情况下,我可能在核心问题上是错误的(尽管DO总是在主线程上放置UI更新)。你应该更新你的代码到你正在使用的任何东西,并确认正在调用refreshTable:。这将有助于我们缩小问题的范围。 – dylanthelion

0

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

兴趣的人的代码:

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() 
} 
相关问题