'iOS 14 UIColorPicker eyedropper tool not returning selected color
I am currently trying to implement the new iOS 14 UIColorPicker. Everything works great, except the eye dropper
functionality of the UIColorPicker. After selecting the the eye dropper and sampling a color, the default behavior should be to re-open the UIColorPicker with your selected color as the active one. For some reason, this does not happen. Here is my implementation, its pretty standard, so I'm not sure why the eyedropper isnt behaving as expected.
I have these functions that are passed as the selectors for when I have some UI elements pressed
@objc func pickColorSky(sender: UIControl){
presentColorPicker(tag: 1, sender: sender)
}
@objc func pickColorBackground(sender: UIControl){
presentColorPicker(tag: 2, sender: sender)
}
@objc func pickColorGround(sender: UIControl){
presentColorPicker(tag: 3, sender: sender)
}
Here is the function that presents the UIColorPickerView itself
@objc private func presentColorPicker(tag: Int, sender: UIControl){
let vc = UIColorPickerViewController()
vc.supportsAlpha = false
vc.delegate = self
vc.view.tag = tag
vc.modalPresentationStyle = .popover
vc.popoverPresentationController?.sourceView = sender
vc.popoverPresentationController?.sourceRect = sender.bounds
self.present(vc, animated: true)
}
And the delegate methods to handle the interacting with the color picker
extension myViewController: UIColorPickerViewControllerDelegate {
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
guard let options = editor?.apiView?.getRenderingOptions() else { return }
if viewController.view.tag == 1 {
let newColor = getMobileApiColor(color: viewController.selectedColor)
options.skyColor = newColor
skyRow.color.backgroundColor = newColor.uiColor
}
else if viewController.view.tag == 2 {
let newColor = getMobileApiColor(color: viewController.selectedColor)
options.backgroundColor = newColor
backgroundRow.color.backgroundColor = newColor.uiColor
}
else if viewController.view.tag == 3 {
let newColor = getMobileApiColor(color: viewController.selectedColor)
options.groundColor = newColor
groundRow.color.backgroundColor = newColor.uiColor
}
editor?.modelView?.setNeedsDisplay()
}
Solution 1:[1]
Try this method colorPickerViewControllerDidSelectColor
extension ViewController: UIColorPickerViewControllerDelegate {
// Called once you have finished picking the color.
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
self.view.backgroundColor = viewController.selectedColor
}
// Called on every color selection done in the picker.
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
self.view.backgroundColor = viewController.selectedColor
}
}
Solution 2:[2]
You need to hold on to the picker object as a class member like this:
private lazy var colorPicker = makeColorPicker()
private func makeColorPicker() -> UIColorPickerViewController {
let vc = UIColorPickerViewController()
vc.delegate = self
vc.supportsAlpha = false
return vc
}
Otherwise, it is removed from memory before you complete the eye-dropper step.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Yogesh Patel |
Solution 2 | James Grote |