[英]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
这是反映错误的记录( 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.