iOS 14 UIColorPicker的eyedropper取色工具无法返回选中颜色如何解决
问题根因
你当前仅实现了UIColorPickerViewControllerDelegate的colorPickerViewControllerDidFinish回调,未满足滴管功能的交互逻辑要求:
- 滴管采样完成后,系统默认触发的是实时选择回调
colorPickerViewControllerDidSelectColor:,而非结束回调 - 你每次弹出选择器都新建
UIColorPickerViewController实例,未将已选中/采样的颜色赋值给新实例的selectedColor属性,无法实现颜色回填 - 将业务tag存储在
vc.view上存在风险,系统内部可能修改视图层级覆盖tag值
修复方案
1. 新增属性存储选中颜色与业务tag
先在你的myViewController类中新增以下属性和分类:
// 存储不同业务场景对应的选中颜色,初始值替换为你自己的默认色 private var selectedColors: [Int: UIColor] = [ 1: UIColor.white, 2: UIColor.lightGray, 3: UIColor.brown ] // 给UIColorPickerViewController加关联对象存储业务tag,避免view.tag被覆盖 private var pickerTagKey: UInt8 = 0 extension UIColorPickerViewController { var businessTag: Int { get { objc_getAssociatedObject(self, &pickerTagKey) as? Int ?? 0 } set { objc_setAssociatedObject(self, &pickerTagKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } }
2. 修改弹出选择器的方法
给新建的选择器实例回填上一次选中的颜色:
@objc private func presentColorPicker(tag: Int, sender: UIControl){ let vc = UIColorPickerViewController() vc.supportsAlpha = false vc.delegate = self vc.businessTag = tag vc.selectedColor = selectedColors[tag] ?? .white vc.modalPresentationStyle = .popover vc.popoverPresentationController?.sourceView = sender vc.popoverPresentationController?.sourceRect = sender.bounds self.present(vc, animated: true) }
3. 补充完整代理方法
同时实现实时选择回调和结束回调:
extension myViewController: UIColorPickerViewControllerDelegate { // 实时选择回调,滴管采样完成后会触发此方法更新选中色 func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) { let tag = viewController.businessTag selectedColors[tag] = viewController.selectedColor } func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) { guard let options = editor?.apiView?.getRenderingOptions() else { return } let tag = viewController.businessTag guard let selectedColor = selectedColors[tag] else { return } let newColor = getMobileApiColor(color: selectedColor) switch tag { case 1: options.skyColor = newColor skyRow.color.backgroundColor = newColor.uiColor case 2: options.backgroundColor = newColor backgroundRow.color.backgroundColor = newColor.uiColor case 3: options.groundColor = newColor groundRow.color.backgroundColor = newColor.uiColor default: break } editor?.modelView?.setNeedsDisplay() } }
内容的提问来源于stack exchange,提问作者Benjamin Morris
相关产品推荐
相关产品推荐

