繁体   English   中英

如何在自定义 UIView 上显示 CGPoints

[英]How to display CGPoints on custom UIView

我有一个小项目,它代表一个带有报告的应用程序,用户可以在自定义CanvasView上绘制,然后到 select 绘制每个涂鸦。 当用户单击 Save UIButton时,报告将被序列化并保存在CoreData中。 当用户单击任何报告进行查看后,它将被带到DetailsVC中,报告将从CoreData反序列化,并且将能够在CanvasView上看到涂鸦,但不再绘制。 问题是没有向我显示CanvasView (DetailsVC)上的涂鸦,但在控制台中说涂鸦数组不是空的并且是从CoreData加载的。

编辑:我认为问题出在下面我认为正在通过一个空数组并尝试 append CGPoints但我不知道如何解决它的行上。 谁能帮我实现一个 function 像:

func parseScribbleData(_ bytes: [UInt8]) -> [[CGPoint]] {

}

https://github.com/tygruletz/SelectScribbles/blob/master/SelectScribbles/Communications/TTableDeserializer.swift#L34

这是我的演示项目: https://github.com/tygruletz/SelectScribbles

这是反映错误的记录( CanvasView缺少 CGPoints): 在此处输入图像描述

这是我反序列化Scribbles的方法:

class TTableDeserializer: NSObject {

    static let sharedInstance = TTableDeserializer()

    // Deserialize all the damageItems recorded from the Report
    func deserializeDamageItemsFor(report: DefectReport) -> [DamageItem] {

        let damageLinesTTable: TTable = TTable(binaryTable: Data(), format: .bin1)
        var damageItems: [DamageItem] = []

        // Get the DamageList with damage items for selected Report.
        damageLinesTTable.deStreamBin(binaryData: report.damageLines ?? Data(), format: .bin1)

        damageLinesTTable.tableRows.forEach { row in

            var damageItem: DamageItem = DamageItem(name: row.cell[0].sData,
                                                    scribbles: [])

            // All Scribbles
            var allCGPoints = [[CGPoint]]()

            damageItem.scribbles.forEach { scribble in

                var scribbleCGPoints = [CGPoint]()
                scribble.forEach { coordinate in

                    let point = CGPoint(
                        x: CGFloat(UInt8(row.cell[3].iData())),
                        y: CGFloat(UInt8(row.cell[3].iData()) & (~0 >> 1))
                    )
                    scribbleCGPoints.append(point)
                }
                allCGPoints.append(scribbleCGPoints)
            }

            damageItem.scribbles = allCGPoints

            damageItems.append(damageItem)

            print("----------   DESERIALIZATION FOR DAMAGE ITEM '\(row.cell[0].sData.capitalized)' STARTED..........  ----------")
            print("Dmg Item Name:     \(row.cell[0].sData)")
            print("Dmg Item Scribble: \(row.cell[1].binData())")
            print("----------   DESERIALIZATION FOR DAMAGE ITEM '\(row.cell[0].sData.capitalized)' ENDED  ----------\n\n")
        }
        return damageItems
    }
}

感谢您阅读本文!

请参阅此拉取请求,该请求解决了一些问题:

  • 我们希望在 CoreData 中对损坏数组进行编码,以使其捕获涂鸦数组。 现在您似乎想要存储一个整数数组,并且您确实想要在DamageItem中捕获该[[CGPoint]]结构。

  • 最简单的方法是让DamageItem符合Codable ,然后用标准的 Foundation 编码器(我使用JSONEncoder / JSONDecoder )替换所有复杂的编码。

    这不仅正确地捕捉到了DamageItem的丰富性,而且从根本上简化了编码/解码过程;

    编码只是:

     report.damageLines = try JSONEncoder().encode(damages)

    解码就是:

     let items = try JSONDecoder().decode([DamageItem].self, from: report.damageLines)
  • 如果您希望您的DetailsReport视图 controller 享受“选择损坏并突出显示适当的涂鸦”功能(就像我们为您的CreateReport所做的那样),您需要更新自定义表格单元格以捕获选定的损坏并让它通过沿着CanvasView

    您还希望DetailsReport中的didSelectRowAt重新加载第一部分(这样您就可以看到选定的损坏)。


无关,我还建议:

  • UIBezierPath例程移出 model 文件夹(因为它不是模型)。

  • 出于同样的原因,也将CanvasView移动到View文件夹中。

您可以使用Swift.Codable序列化和反序列化Data 由于CGFloat已经符合Codable ,因此无需将您自己的Data写入CGFloat代码。 此外Array<SomeCodable>也是Codable所以[CGFloat]也是Codable

将 CGFloat 转换为数据:

let numbers: [CGFloat] = [1,2,3,4]
guard let data = try? JSONEncoder().encode(numbers) else {
  fatalError("cannot convert data")
}

将数据转换为 CGFloat:

guard let numbersFromData = try? JSONDecoder().decode([CGFloat].self, from: data) else {
  fatalError("cannot decode floats")
}

我怀疑您对问题所在位置的评估是正确的(尽管我认为问题早于几行

您来自 Github 的代码:

 // Get the DamageList with damage items for selected Report.
    damageLinesTTable.deStreamBin(binaryData: report.damageLines ?? Data(), format: .bin1)

    damageLinesTTable.tableRows.forEach { row in

        var damageItem: DamageItem = DamageItem(name: row.cell[0].sData,
                                                scribbles: [])

        // All Scribbles
        var allCGPoints = [[CGPoint]]()

        damageItem.scribbles.forEach { scribble in

            var scribbleCGPoints = [CGPoint]()
            scribble.forEach { coordinate in

                let point = CGPoint(
                    x: CGFloat(UInt8(row.cell[3].iData())),
                    y: CGFloat(UInt8(row.cell[3].iData()) & (~0 >> 1))
                )
                scribbleCGPoints.append(point)
            }
            allCGPoints.append(scribbleCGPoints)
        }

damageLinesTTable.tableRows.forEach块中为每一行创建一个新的 DamageItem 实例

var damageItem: DamageItem = DamageItem(name: row.cell[0].sData,
                                                scribbles: [])

在这里,您正在使用一个空的涂鸦数组初始化damageItem 变量。

然后几个班轮稍后你这样做:

damageItem.scribbles.forEach { scribble in ...

遍历该涂鸦数组。 但是,该数组将始终为空,因为您刚刚使用空数组初始化了该damageItem!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM