What I want to do is building a TLV editor. The TLV-structur consists of constructed and normal items. When I add an item to a construction I need to update the length of the construction as well as the length in all above parent constructions.
I tried to do this by adding var parent: Construction?
to the Construction model.
For adding it looks quite well, but when removing it gets out of sync. Anybody a good idea what is wrong? Or is there a better solution?
Here is a short demo: https://github.com/frcocoatst/test1
Model.swift:
class Item: Equatable, CustomStringConvertible {
var id: Int?
var tag: String = "TAG"
var length: Int = 1
var value: String = "VALUE"
...
class Construction: Equatable {
var id: Int?
var clength: Int = 0
var parent: Construction?
var items = [Any]()
...
ViewController.swift add an item:
@IBAction func addItemAction(_ sender: Any) {
print("addItemAction")
// Make sure that there is a target construction to add a new item to.
guard let construction = getConstructionForSelectedItem() else { return }
// Create and get the instance of the new item.
let newItem = viewModel.addItem(
tag: itemTagOutlet.stringValue,
length: itemValueOutlet.stringValue.count/2,
value: itemValueOutlet.stringValue,
comment: "ItemComment",
construction: construction)
print("update construction length")
construction.clength += itemValueOutlet.stringValue.count/2
...
// for all parents add length
var parentConstruction = construction.parent
while let pConstruction = parentConstruction
{
print(pConstruction)
print(">>>update parent construction length")
parentConstruction?.clength += itemValueOutlet.stringValue.count/2
parentConstruction = pConstruction.parent
}
print("reload")
// Reload the outline view and expand the construction.
outlineView.reloadData()
outlineView.expandItem(construction)
ViewController.swift remove an item:
@IBAction func deleteItemAction(_ sender: Any) {
print("deleteItemAction")
let selectedRow = outlineView.selectedRow
var result = false
if let selectedItem = outlineView.item(atRow: selectedRow) as? Item {
guard let construction = getConstructionForSelectedItem() else { return }
let ctr = selectedItem.length
construction.clength -= ctr
viewModel.remove(item: selectedItem, from: construction)
//
print("remove item update construction length")
...
// for all parents subtract length
var parentConstruction = construction.parent
while let pConstruction = parentConstruction
{
print(pConstruction)
print(">>>update parent construction length")
parentConstruction?.clength -= ctr
parentConstruction = pConstruction.parent
}
....