[英]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.