簡體   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