如何将第二个表格视图的值与第一个表格视图的单击行的关系分开?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将第二个表格视图的值与第一个表格视图的单击行的关系分开?相关的知识,希望对你有一定的参考价值。
我是Swift的新手,需要您的帮助。
在我的应用中,我有两个视图控制器。两者都具有动态表视图。第一个视图控制器及其表显示了一些类别(称为组),第二个视图控制器显示了属于这些类别的一些对象(称为单个组)。用户可以在两个表视图中添加和删除所有内容。我将每个表视图的值保存在数组中,并在核心数据中使用两个实体(每个表视图一个实体)。在核心数据中,我将类别/对象的ID保存为UUID,将标题保存为字符串。另外,每个UUID都有一个索引,因此每个值都有其自己的位置。
现在是我的问题:
当我单击第一个表视图中的一行时,将显示下一个视图控制器(detailViewController)。我可以添加一些东西,一切正常。但是,当我返回并在第一个表格视图中单击另一行时,它再次在detailViewController上显示了相同的内容。
所以我认为我必须将第二个表格视图中的对象与第一个表格视图中的每一行分开。但是我不知道该怎么做。
我想到的是从secondViewController中保存与第一个表视图中的行值的索引有关的数组。困难是我将应用程序中的所有内容分离到了不同的文件中。因此,Core Data拥有自己的文件以及具有数组和视图控制器本身的存储。
因此,我不知道您到底需要什么代码。我希望这足够了:
班级组
import Foundation
class Group {
private(set) var groupId : UUID
private(set) var groupTitle : String
init(groupTitle: String) {
self.groupId = UUID()
self.groupTitle = groupTitle
}
init(groupId: UUID, groupTitle: String) {
self.groupId = groupId
self.groupTitle = groupTitle
}
}
Class SingleGroup
import Foundation
class SingleGroup {
private(set) var singleGroupId : UUID
private(set) var singleGroupName : String
private(set) var singleGroupAmount : Double
private(set) var singleGroupTimeStamp : Int64
init(singleGroupName: String, singleGroupAmount: Double, singleGroupTimeStamp: Int64) {
self.singleGroupId = UUID()
self.singleGroupName = singleGroupName
self.singleGroupAmount = singleGroupAmount
self.singleGroupTimeStamp = singleGroupTimeStamp
}
init(singleGroupId: UUID, singleGroupName: String, singleGroupAmount: Double, singleGroupTimeStamp: Int64) {
self.singleGroupId = singleGroupId
self.singleGroupName = singleGroupName
self.singleGroupAmount = singleGroupAmount
self.singleGroupTimeStamp = singleGroupTimeStamp
}
}
存储组
import CoreData
class Storage {
static let storage : Storage = Storage()
private var groupIndexToIdDict : [Int:UUID] = [:]
private var currentIndex : Int = 0
private(set) var managedObjectContext : NSManagedObjectContext
private var managedContextHasBeenSet: Bool = false
//need to init the ManageObjectContext, it will be overwritten when setManagedContext is called from the view controller
init() {
managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
}
func setManagedContext(managedObjectContext: NSManagedObjectContext) {
self.managedObjectContext = managedObjectContext
self.managedContextHasBeenSet = true
let groups = CoreDataHelper.readGroupsFromCoreData(fromManagedObjectContext: self.managedObjectContext)
currentIndex = CoreDataHelper.count
for (index, group) in groups.enumerated() {
groupIndexToIdDict[index] = group.groupId
}
}
func addGroup(groupToBeAdded: Group) {
if managedContextHasBeenSet {
// add group UUID to the dictionary
groupIndexToIdDict[currentIndex] = groupToBeAdded.groupId
// call Core Data Helper to create the new group
CoreDataHelper.createGroupInCoreData(groupToBeCreated: groupToBeAdded, intoManagedObjectContext: self.managedObjectContext)
// increase index
currentIndex += 1
}
}
存储单组
import CoreData
class SingleGroupStorage {
static let singleGroupStorage : SingleGroupStorage = SingleGroupStorage()
private var singleGroupIndexToIdDict : [Int:UUID] = [:]
private var currentIndex: Int = 0
private(set) var managedObjectContext : NSManagedObjectContext
private var managedContextHasBeenSet: Bool = false
// need to init the ManagedObjectCOntext, it will be overwritten when setManagedContext is called from the view controller
init() {
managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
}
func setManagedContext(managedObjectContext: NSManagedObjectContext) {
self.managedObjectContext = managedObjectContext
self.managedContextHasBeenSet = true
let singleGroups = SingleGroupsCoreDataHelper.readSingleGroupsFromCoreData(fromManagedObjectContext: self.managedObjectContext)
currentIndex = SingleGroupsCoreDataHelper.countSingleGroup
for (index, singleGroup) in singleGroups.enumerated() {
singleGroupIndexToIdDict[index] = singleGroup.singleGroupId
}
}
func addSingleGroup(singleGroupToBeAdded: SingleGroup) {
if managedContextHasBeenSet {
// add singlegroup UUID to the dictionary
singleGroupIndexToIdDict[currentIndex] = singleGroupToBeAdded.singleGroupId
// call Core Data Helper to create the new single group
SingleGroupsCoreDataHelper.createSingleGroupInCoreData(singleGroupToBeCreated: singleGroupToBeAdded, intoManagedObjectContext: self.managedObjectContext)
// increase index
currentIndex += 1
}
}
核心数据助手组
import Foundation
import CoreData
class CoreDataHelper {
private(set) static var count : Int = 0
static func createGroupInCoreData(groupToBeCreated: Group, intoManagedObjectContext: NSManagedObjectContext) {
// create an entity and new group record
let groupEntity = NSEntityDescription.entity(forEntityName: "Groups", in: intoManagedObjectContext)!
let newGroupToBeCreated = NSManagedObject(entity: groupEntity, insertInto: intoManagedObjectContext)
newGroupToBeCreated.setValue(groupToBeCreated.groupId, forKey: "groupId")
newGroupToBeCreated.setValue(groupToBeCreated.groupTitle, forKey: "groupTitle")
do {
try intoManagedObjectContext.save()
count += 1
} catch let error as NSError {
print("Could not save group. (error), (error.userInfo)")
}
}
static func readGroupFromCoreData(groupIdToBeRead: UUID, fromManagedObjectContext: NSManagedObjectContext) -> Group? {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Groups")
let groupIdPredicate = NSPredicate(format: "groupId = %@", groupIdToBeRead as CVarArg)
fetchRequest.predicate = groupIdPredicate
do {
let fetchedGroupsFromCoreData = try fromManagedObjectContext.fetch(fetchRequest)
let groupManagedObjectToBeRead = fetchedGroupsFromCoreData[0] as! NSManagedObject
return Group.init(
groupId: groupManagedObjectToBeRead.value(forKey: "groupId") as! UUID,
groupTitle: groupManagedObjectToBeRead.value(forKey: "groupTitle") as! String)
} catch let error as NSError {
// TODO error handling
print("Could not read group. (error), (error.userInfo)")
return nil
}
}
核心数据助手单个组
import Foundation
import CoreData
class SingleGroupsCoreDataHelper {
private(set) static var countSingleGroup : Int = 0
static func createSingleGroupInCoreData(singleGroupToBeCreated: SingleGroup, intoManagedObjectContext: NSManagedObjectContext) {
// create an entity and new single group record
let singleGroupEntity = NSEntityDescription.entity(forEntityName: "SingleGroups", in: intoManagedObjectContext)!
let newSingleGroupToBeCreated = NSManagedObject(entity: singleGroupEntity, insertInto: intoManagedObjectContext)
newSingleGroupToBeCreated.setValue(singleGroupToBeCreated.singleGroupId, forKey: "singleGroupId")
newSingleGroupToBeCreated.setValue(singleGroupToBeCreated.singleGroupName, forKey: "singleGroupName")
newSingleGroupToBeCreated.setValue(singleGroupToBeCreated.singleGroupAmount, forKey: "singleGroupAmount")
newSingleGroupToBeCreated.setValue(singleGroupToBeCreated.singleGroupTimeStamp, forKey: "singleGroupTimeStamp")
do {
try intoManagedObjectContext.save()
countSingleGroup += 1
} catch let error as NSError {
print("Could not save group. (error), (error.userInfo)")
}
}
static func readSingleGroupFromCoreData(singleGroupIdToBeRead: UUID, fromManagedObjectContext: NSManagedObjectContext) -> SingleGroup? {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SingleGroups")
let singleGroupIdPredicate = NSPredicate(format: "singleGroupId = %@", singleGroupIdToBeRead as CVarArg)
fetchRequest.predicate = singleGroupIdPredicate
do {
let fetchedSingleGroupsFromCoreData = try fromManagedObjectContext.fetch(fetchRequest)
let singleGroupManagedObjectToBeRead = fetchedSingleGroupsFromCoreData[0] as! NSManagedObject
return SingleGroup.init(
singleGroupId: singleGroupManagedObjectToBeRead.value(forKey: "singleGroupId") as! UUID,
singleGroupName: singleGroupManagedObjectToBeRead.value(forKey: "singleGroupName") as! String,
singleGroupAmount: singleGroupManagedObjectToBeRead.value(forKey: "singleGroupAmount") as! Double,
singleGroupTimeStamp: singleGroupManagedObjectToBeRead.value(forKey: "singleGroupTimeStamp") as! Int64)
} catch let error as NSError {
// TODO error handling
print("Could not read single group. (error), (error.userInfo)")
return nil
}
}
第一张表视图
override func numberOfSections(in tableView: UITableView) -> Int {
// return fetchedResultsController.sections?.count ?? 0
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return objects.count
return Storage.storage.count()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "GroupsTableViewCell", for: indexPath) as! GroupsTableViewCell
if let object = Storage.storage.readGroup(at: indexPath.row) {
cell.groupTitleLabel!.text = object.groupTitle
}
return cell
}
Segue到detailViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetailSegue" {
if let indexPath = tableView.indexPathForSelectedRow {
let navTitle = Storage.storage.readGroup(at: indexPath.row)
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.title = navTitle?.groupTitle
}
}
}
第二张表视图
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return objects.count
return SingleGroupStorage.singleGroupStorage.countSingleGroup()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SingleGroupsTableViewCell", for: indexPath) as! SingleGroupsTableViewCell
if let object = SingleGroupStorage.singleGroupStorage.readSingleGroup(at: indexPath.row) {
cell.singleGroupNameLabel!.text = object.singleGroupName
cell.singleGroupAmountLabel!.text = String(format: "%.2f", object.singleGroupAmount)
cell.singleGroupDateLabel!.text = DateHelper.convertDate(date: Date.init(seconds: object.singleGroupTimeStamp))
}
return cell
}
我几周以来一直在寻找解决方案,但找不到任何东西。
希望您能理解我的问题,并有任何解决方案或提示来解决。
更新:
组-读取(at:)
func readGroup(at: Int) -> Group? {
if managedContextHasBeenSet {
// check input index
if at < 0 || at > currentIndex - 1 {
// TODO error handling
print("Can not read Groups.")
return nil
}
// get group UUID from dictionary
let groupUUID = groupIndexToIdDict[at]
let groupReadFromCoreData: Group?
groupReadFromCoreData = CoreDataHelper.readGroupFromCoreData(groupIdToBeRead: groupUUID!, fromManagedObjectContext: self.managedObjectContext)
return groupReadFromCoreData
}
return nil
}
同一组相同
func readSingleGroup(at: Int) -> SingleGroup? {
if managedContextHasBeenSet {
// check input index
if at < 0 || at > currentIndex - 1 {
// TODO error handling
print("Can not read SingleGroups.")
return nil
}
// get single group UUID from dicitionary
let singleGroupUUID = singleGroupIndexToIdDict[at]
let singleGroupReadFromCoreData: SingleGroup?
singleGroupReadFromCoreData = SingleGroupsCoreDataHelper.readSingleGroupFromCoreData(singleGroupIdToBeRead: singleGroupUUID!, fromManagedObjectContext: self.managedObjectContext)
return singleGroupReadFromCoreData
}
return nil
}
更新:
我已经更新了核心数据关系(一对多),现在可以正常工作!谢谢你的提示。
但是现在我有一个新问题:
在我的Group ViewController(带有第一个表格视图)上,我通过警报添加新值。在更新代码之前,当您添加新值时,tableview将重新加载数据并在tableview中显示新值。由于我更新了代码,因此tableview会重新加载数据,但不显示它。我必须切换视图控制器,然后返回以显示它。
我在代码中的任何地方都尝试了groupTableView.reloadData(),但无法正常工作。希望你能帮助我。
代码(组)MasterViewController:
//
// MasterViewController.swift
// OhMyMoney
//
// Created by Mina Kurah on 14.01.20.
// Copyright © 2020 MyOrganisation. All rights reserved.
//
import UIKit
import CoreData
class MasterViewController: UITableViewController {
var groups: [Groups] = []
@IBOutlet weak var groupsTableView: UITableView!
var groupsTextField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
self.groupsTableView.delegate = self
self.groupsTableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
// Core date initialization
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
// create alert
let alert = UIAlertController(
title: "Could not get app delegate",
message: "Could not get app delegate, unexpected error occured. Try again later.",
preferredStyle: .alert)
// add OK action
alert.addAction(UIAlertAction(title: "OK", style: .default))
// show alert
self.present(alert, animated: true)
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Groups> = Groups.fetchRequest()
do {
groups = try managedContext.fetch(fetchRequest)
groupsTableView.reloadData()
} catch {
// TODO: error handling
print("Could not fetch groups")
}
navigationItem.leftBarButtonItem = editButtonItem
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject))
navigationItem.rightBarButtonItem = addButton
}
// MARK: - add new Group
@objc func insertNewObject() {
let addButtonAlert = UIAlertController(title: "Neue Gruppe", message: "Füge eine neue Gruppe deiner Liste hinzu", preferredStyle: .alert)
addButtonAlert.addTextField { (UITextField) in
self.groupsTextField = UITextField
self.groupsTextField?.placeholder = "Name der Gruppe"
self.groupsTextField?.clearButtonMode = .whileEditing
}
let okAction = UIAlertAction(title: "Hinzufügen", style: .default, handler: addNewGroup)
let cancelAction = UIAlertAction(title: "Abbrechen", style: .cancel, handler: nil)
addButtonAlert.addAction(okAction)
addButtonAlert.addAction(cancelAction)
self.present(addButtonAlert, animated: true)
}
func addNewGroup(_:UIAlertAction) -> Void {
let group = Groups(groupId: UUID(), groupTitle: groupsTextField!.text ?? "")
do {
try group?.managedObjectContext?.save()
groupsTableView.reloadData()
} catch {
print("Could not save group")
}
}
// MARK: - Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destination = segue.destination as? DetailViewController,
let selectedRow = self.groupsTableView.indexPathForSelectedRow?.row else {
return
}
destination.group = groups[selectedRow]
destination.title = groups[selectedRow].groupTitle
}
// MARK: - delete Group
func deleteGroup(at indexPath: IndexPath) {
let group = groups[indexPath.row]
guard let managedContext = group.managedObjectContext else {
return
}
managedContext.delete(group)
do {
try managedContext.save()
groups.remove(at: indexPath.row)
groupsTableView.deleteRows(at: [indexPath], with: .automatic)
} catch {
//TODO: error handling
print("Could not delete Group")
groupsTableView.reloadRows(at: [indexPath], with: .automatic)
}
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groups.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = groupsTableView.dequeueReusableCell(withIdentifier: "GroupsTableViewCell", for: indexPath) as! GroupsTableViewCell
let object = groups[indexPath.row]
cell.groupTitleLabel?.text = object.groupTitle
return cell
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
deleteGroup(at: indexPath)
}
}
}
以上是关于如何将第二个表格视图的值与第一个表格视图的单击行的关系分开?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 5. 从第二个表格视图单元格(第二个 indexpath.row )显示数组