Как разделить значения второго табличного представления по отношению к нажатой строке первого табличного представления? - PullRequest
3 голосов
/ 27 января 2020

Я новичок в Swift и мне нужна ваша помощь.

В моем приложении у меня есть два контроллера вида. Оба имеют динамическое c табличное представление. Первый контроллер представления и его таблица отображают некоторые категории (называемые группами), а второй - некоторые объекты (называемые одиночными группами), которые относятся к этим категориям. Пользователь может добавлять и удалять весь контент в обоих табличных представлениях. Я сохраняю значения из каждого табличного представления в массиве и использую две сущности в основных данных (одна сущность для каждого табличного представления). В основных данных я сохраняю идентификатор категории / объекта как UUID и заголовок как строку. Также каждый UUID получает индекс, поэтому у каждого значения есть свое место.

Теперь к моей проблеме:

Когда я нажимаю на строку в первом табличном представлении, следующий контроллер представления (detailViewController) показывает вверх. Я могу добавить некоторые вещи, и все работает отлично. Но когда я go возвращаюсь и нажимаю на другую строку в первом табличном представлении, это снова показывает то же самое в 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
    }
}

Класс 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
        }
    }

Хранилище SingleGroup

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
    }

Переход к деталям ViewController

    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
    }

Я искал решение несколько недель назад, но не смог ничего найти.

Надеюсь, вы понимаете, в чем моя проблема, и имеете любые решения или советы, как ее решить.

Обновление:

Группы - прочитайте (по адресу:)

    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
    }
...