Ios 通过两个具有节的不同NSFetchedResultsController查看单个表
大家早上好。我使用的是Swift 3.1.1,Xcode 8.3.2。我需要通过两个不同的NSFetchedResultsController将单个表视图连接到核心数据中的两个不同表(实体)。我创建了两个NSFetchedResultsController,甚至从表中提取了数据,但我面临的问题是如何告诉表视图第一个控制器应该响应第一节,第二个控制器应该负责第二节。 我可以向您展示代码:Ios 通过两个具有节的不同NSFetchedResultsController查看单个表,ios,uitableview,core-data,swift3,nsfetchedresultscontroller,Ios,Uitableview,Core Data,Swift3,Nsfetchedresultscontroller,大家早上好。我使用的是Swift 3.1.1,Xcode 8.3.2。我需要通过两个不同的NSFetchedResultsController将单个表视图连接到核心数据中的两个不同表(实体)。我创建了两个NSFetchedResultsController,甚至从表中提取了数据,但我面临的问题是如何告诉表视图第一个控制器应该响应第一节,第二个控制器应该负责第二节。 我可以向您展示代码: import UIKit class ViewController: UIViewController {
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tv: UITableView!
@IBAction func pressed(_ sender: UIButton) {
ModelA.read { table1 in
ModelB.read { table2 in
if table1.isEmpty {
ModelA.save(recordToSave: [(a: 1, b: "a"), (a: 2, b: "b"), (a: 3, b: "c")]) {
ModelB.save(recordToSave: [(a: 4, b: 5.0, c: true), (a: 6, b: 7.0, c: false)]) {
self.tvReload()
}
}
} else {
self.tvReload()
}
}
}
}
var fetchedResultsControllerForModelA = CoreDataFunctions.fetchedResultsController
var fetchedResultsControllerForModelB = CoreDataFunctions.fetchedResultsController
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tvReload()
}
func modelOfTableA(indexPath: IndexPath) -> (forLabel1: String, forLabel2: String, forLabel3: String)? {
if let fetchedResultsControllerForModelA = CoreDataFunctions.getNSManagedObjectForIndexPathOfTable(fetchedResultsController: fetchedResultsControllerForModelA, indexPath: indexPath) {
if let model = ModelA.read(nsmanagedobject: fetchedResultsControllerForModelA) {
return (forLabel1: "\(model.a)", forLabel2: model.b, forLabel3: "")
}
}
return nil
}
func modelOfTableB(indexPath: IndexPath) -> (forLabel1: String, forLabel2: String, forLabel3: String)? {
if let fetchedResultsControllerForModelB = CoreDataFunctions.getNSManagedObjectForIndexPathOfTable(fetchedResultsController: fetchedResultsControllerForModelB, indexPath: indexPath) {
if let model = ModelB.read(nsmanagedobject: fetchedResultsControllerForModelB) {
return (forLabel1: "\(model.a)", forLabel2: "\(model.b)", forLabel3: "\(model.c)")
}
}
return nil
}
func tvReload() {
fetchedResultsControllerForModelA = CoreDataFunctions(tableName: .a).fetchedResultsController(keyForSort: ModelA.a.rawValue, searchParameters: nil)
fetchedResultsControllerForModelB = CoreDataFunctions(tableName: .b).fetchedResultsController(keyForSort: ModelB.a.rawValue, searchParameters: nil)
do {
try fetchedResultsControllerForModelA?.performFetch()
try fetchedResultsControllerForModelB?.performFetch()
DispatchQueue.main.async {
self.tv.reloadData()
}
} catch {
print("Error")
}
}
func numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let sections1 = fetchedResultsControllerForModelA?.sections {
if let sections2 = fetchedResultsControllerForModelB?.sections {
return sections1[section].numberOfObjects + sections2[section].numberOfObjects
}
return sections1[section].numberOfObjects
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
if indexPath.section == 0 {
if let modelOfTable = modelOfTableA(indexPath: indexPath) {
cell.l1.text = modelOfTable.forLabel1
cell.l2.text = modelOfTable.forLabel2
cell.l3.text = modelOfTable.forLabel3
}
} else {
if let modelOfTable = modelOfTableB(indexPath: indexPath) {
cell.l1.text = modelOfTable.forLabel1
cell.l2.text = modelOfTable.forLabel2
cell.l3.text = modelOfTable.forLabel3
}
}
return cell
}
}
我找不到关于这个主题的任何教程,所以我在那里问了一个问题。我不想在核心数据中使用单个实体的继承,因为在现实生活中这是不可能的。
谢谢你的帮助和建议 好的-我下载了你的代码,有几个问题 1) 如果希望数据填充表中的两个部分,则该表必须有两个部分-当前,您仅返回1,因此请使用此选项(尽管您可能希望/需要根据检索到的数据进行不同的处理): 2) 对于每个部分中的行数,您的代码很接近,但不完全正确
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
if let sections = fetchedResultsControllerForModelA?.sections {
return sections[0].numberOfObjects
}
} else {
if let sections = fetchedResultsControllerForModelB?.sections {
return sections[0].numberOfObjects
}
}
return 0
}
3) 对于实际的cellForRowAtIndexPath数据,您的代码也很接近,但您需要跟踪每个部分要获取的数据
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
if indexPath.section == 0 {
if let modelOfTable = modelOfTableA(indexPath: indexPath) {
cell.l1.text = modelOfTable.forLabel1
cell.l2.text = modelOfTable.forLabel2
cell.l3.text = modelOfTable.forLabel3
}
} else {
// Each "Table data model" has only one section... since this is the 2nd table section, we need
// to change the section of the index path for our call to the data model
let dataIndexPath = IndexPath(row: indexPath.row, section: 0)
if let modelOfTable = modelOfTableB(indexPath: dataIndexPath) {
cell.l1.text = modelOfTable.forLabel1
cell.l2.text = modelOfTable.forLabel2
cell.l3.text = modelOfTable.forLabel3
}
}
return cell
}
这应该会让您走上正轨。为什么您不是每个部分的单独数组?即使没有NSFetchedResultsController,我也可以为两个部分使用单个元组数组。我认为这是不对的,但是,你能解释一下这部分吗?让dataIndexPath=IndexPath(row:IndexPath.row,section:0)有两个数据模型——每个表节一个。但每个数据模型只有一个数据部分。因此,如果您调用
modelOfTableB()
并在第二节中传递表的第一行索引路径,您将询问“第1节,第0行”。。。这将失败,因为“第1节”是第二节(基于零的索引)。好的,我想我现在明白了!再次感谢你!
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
if indexPath.section == 0 {
if let modelOfTable = modelOfTableA(indexPath: indexPath) {
cell.l1.text = modelOfTable.forLabel1
cell.l2.text = modelOfTable.forLabel2
cell.l3.text = modelOfTable.forLabel3
}
} else {
// Each "Table data model" has only one section... since this is the 2nd table section, we need
// to change the section of the index path for our call to the data model
let dataIndexPath = IndexPath(row: indexPath.row, section: 0)
if let modelOfTable = modelOfTableB(indexPath: dataIndexPath) {
cell.l1.text = modelOfTable.forLabel1
cell.l2.text = modelOfTable.forLabel2
cell.l3.text = modelOfTable.forLabel3
}
}
return cell
}