ios - 从手机发送一个 UIColor 以观看奇怪颜色的结果

标签 ios swift watchkit uicolor

好的。这真的很奇怪。我正在尝试将颜色从手机应用程序传输到其配套的 Watch 应用程序。

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

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

我正在做的是从 watch 向手机发送消息,要求手机提供一组颜色。

手机会编译 UIColor 实例列表,并将它们发送到 watch 。它首先实例化三种标准颜色(UIColor.red、UIColor.green、UIColor.blue),然后附加一些从应用 Storyboard中定义的标签列表中读取的颜色(它从标签中读取文本颜色) ).

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

前三种颜色好看:

The first three (Standard) colors are golden

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

这是应该发生的事情:

These colors should be exactly matched on the Watch

这是实际发生的事情:

The colors are wrong

只有最后一个(奇数)颜色是正确的。颜色在 Storyboard中定义为 RGB( slider )。

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

更新 (2):有人建议我尝试以编程方式添加颜色。这些工作正常,这意味着这开始看起来像一个 Apple 错误。当我收到对我的 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

最佳答案

好的。我有一个解决方法。这绝对是一个错误,但我等不及 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 创建一个新的 CGColor,并将其转换为 sRGB。新的 CGColor 有效。

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

不过,我需要测试内存泄漏。 CG 往往像筛子一样漏水。

关于ios - 从手机发送一个 UIColor 以观看奇怪颜色的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44547727/

相关文章:

ios - Realm 列表未保存数据

ios - 无法更改 Apple Watch 通知中的窗框标题

android - 在 iOS 和 Android 上点赞支付

ios - 无法在iPhone 5s上安装应用

ios - HTTP.Body 参数问题 - Swift

ios - 优化内存 iOS App : UIWebView, Google Maps SDK

ios - 重置主要内容 View - Swift UI

ios - 如何在下载图像和高度限制 swift 改变后更新 tableview 单元格高度?

ios - WatchKit,AttributedString 格式不起作用

swift - 在 NSUserDefaults 中将多个对象传递给 WatchKit