从手机发送UIColor以观察奇怪颜色的结果

时间:2017-06-14 14:33:42

标签: ios swift watchkit uicolor

行。这真的很奇怪。我试图将手机应用中的颜色传输到其配套的Watch应用程序。

标准(UIColor.red等)颜色有效,但IB文件定义的颜色不适用。我得到了奇怪的颜色,这似乎是一个色彩空间问题。

First, here's a VERY simple (and absolutely HIDEOUS) app project that demonstrates this.

我正在做的是从手表向手机发送消息,询问手机的颜色。

手机通过编辑UIColor实例列表并将其发送到手表来强制执行。它通过首先实例化三种标准颜色(UIColor.red,UIColor.green,UIColor.blue),然后添加从应用程序故事板中定义的标签列表中读取的一些颜色来实现这一点(它从标签中读取文本颜色) )。

然后将七个UIColor实例的结果数组序列化并发送到手表,然后反序列化它们,并创建一个简单的标签表;每个都有相应的颜色。

前三种颜色看起来不错:

The first three (Standard) colors are golden

但是,当我从IB中读取颜色时,它们会出现偏斜。

以下是应该发生的事情:

These colors should be exactly matched on the Watch

以下是实际发生的事情:

The colors are wrong

只有最后(奇数)颜色是正确的。故事板中的颜色在RGB(滑块)中定义。

Here's the code in the iOS app that gathers and sends the color

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
    print("iOS App: session(_:,didReceiveMessage:)\n\(message)")
    if let value = message["HI"] as? String {
        if "HOWAYA" == value {
            var colorArray: [UIColor] = [UIColor.red, UIColor.green, UIColor.blue]
            if let primaryViewController = self.window?.rootViewController {
                if let view = primaryViewController.view {
                    for subview in view.subviews {
                        if let label = subview as? UILabel {
                            if let color = label.textColor {
                                colorArray.append(color)
                            }
                        }
                    }
                }
            }
            let colorData = NSKeyedArchiver.archivedData(withRootObject: colorArray)
            let responseMessage = [value:colorData]

            session.sendMessage(responseMessage, replyHandler: nil, errorHandler: nil)
        }
    }
}

Here's the code in the Watch that gets the colors, and instantiates the labels

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
    if let value = message["HOWAYA"] as? Data {
        if let colorArray = NSKeyedUnarchiver.unarchiveObject(with:value) as? [UIColor] {
            self.labelTable.setNumberOfRows(colorArray.count, withRowType: "TestColorTableRow")
            for row in 0..<colorArray.count {
                if let controller = self.labelTable.rowController(at: row) as? TestTableRowController {
                    controller.setLabelColor(colorArray[row])
                }
            }
        }
    }
}

我发送的其他数据(在另一个应用程序中)很好,但颜色有偏差。

有什么想法吗?

更新:有人建议可能序列化是一个问题,所以我分支了这个演示版,并且在iOS中仍然进行了序列化。事实证明没问题。

I created this branch,我在发送邮件之前反序列化:

func colorCrosscheck(_ value: Data) {
    if let colorArray = NSKeyedUnarchiver.unarchiveObject(with:value) as? [UIColor] {
        if let primaryViewController = self.window?.rootViewController {
            if let view = primaryViewController.view {
                for subview in view.subviews {
                    if let containerView = subview as? ViewList {
                        for row in 3..<colorArray.count {
                            if let label = containerView.subviews[row - 3] as? UILabel {
                                label.textColor = colorArray[row]
                            }
                        }
                        break
                    }
                }
            }
        }
    }
}

我做的是添加四个带有明文颜色的标签,这些标签通过我在Watch上使用的相同过程进行着色。

Watch收到消息后几秒钟,iOS中的顶部标签下方会出现四个标签。

结果显示序列化不是问题:

Looks OK on iOS

UPDATE(2):有人建议我尝试以编程方式添加颜色。这些工作正常,这意味着它开始看起来像一个Apple bug。当我得到对DTS事件的回复时,我会报告。

First, here's a new branch that demonstrates adding the colors dynamically.

Here's the relevant section of code(我也搞砸了IB文件):

colorArray.append(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 1.0))
colorArray.append(UIColor(red: 1.0, green: 0.5, blue: 0.0, alpha: 1.0))
colorArray.append(UIColor(red: 0.0, green: 0.0, blue: 0.5, alpha: 1.0))
colorArray.append(UIColor(hue: 1.2, saturation: 1.0, brightness: 0.5, alpha: 1.0))
colorArray.append(UIColor(hue: 1.2, saturation: 0.6, brightness: 0.7, alpha: 1.0))

我在RGB和HSL中添加了5种新的动态颜色。

他们在iOS应用中表现得很好:

Looks Good on iOS (If you're a deranged magpie)

他们也正确传递给Watch:

The first Three The Last Two

1 个答案:

答案 0 :(得分:0)

行。我有一个解决方法。这绝对是一个错误,但我不能等到iOS 11 / WatchOS 4问世。这种解决方法是有效的(到目前为止还有很多测试)。

Here's the branch with the workaround.

if let color = label.textColor {
    if let destColorSpace: CGColorSpace = CGColorSpace(name: CGColorSpace.sRGB) {
        let newColor = color.cgColor.converted(to: destColorSpace, intent: CGColorRenderingIntent.perceptual, options: nil)
        colorArray.append(UIColor(cgColor: newColor!))
    }
}

看起来基于IB的颜色的核心颜色很糟糕。不确定它是如何获得正确的颜色。

我所做的是从原版创建一个新的CGColor,将其转换为sRGB。新的CGColor有效。

这是一个令人讨厌和笨拙的修复,但它应该可以正常工作。

但我需要测试内存泄漏。 CG往往像筛子一样泄漏。