Home > database >  UIView with background color looks different than CALayer with background color. Why, and how to mak
UIView with background color looks different than CALayer with background color. Why, and how to mak

Time:12-20

I created a little project (UnderlinedTextField screenshot

The layer-based underline looks heavier. In looking at it, the color used for anti-aliasing on the layer-based underline is darker than the color used in anti-aliasing the underline for the view-based underline.

Why is that, and what would I change to make them look the same?

(Below is the code for the UnderlinedTextField class, in case you don't want to go look at the Github repo)

/// This is a custom subclass of UITextField that adds a 1-point colored underline under the text field using a CALayer.
/// It implments the `layoutSubviews()` method to reposition the underline layer if the text field is moved or resized.
class UnderlinedTextField: UITextField {

    /// Change this color to change the color used for the underline
    public var underlineColor = UIColor.blue {
        didSet {
            underlineLayer.backgroundColor = underlineColor.cgColor
        }
    }

    private let underlineLayer = CALayer()

    /// Size the underline layer and position it as a one point line under the text field.
    func setupUnderlineLayer() {
        var frame = self.bounds
        frame.origin.y = frame.size.height - 1
        frame.size.height = 1

        underlineLayer.frame = frame
        underlineLayer.backgroundColor = underlineColor.cgColor
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // In `init?(coder:)` Add our underlineLayer as a sublayer of the view's main layer
        self.layer.addSublayer(underlineLayer)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        // in `init(frame:)` Add our underlineLayer as a sublayer of the view's main layer
        self.layer.addSublayer(underlineLayer)
    }

    // Any time we are asked to update our subviews,
    // adjust the size and placement of the underline layer too
    override func layoutSubviews() {
        super.layoutSubviews()
        setupUnderlineLayer()
    }
}

CodePudding user response:

You have in fact given them different colors.

  • The layer's color is set in code and is UIColor.blue.cgColor.

  • The view's color is created in the storyboard and is

      R:0.02 G:0.2 B:1 A:1
    

    as revealed by examining it in the view debugger.

Why? Because you have failed to take into account the storyboard color's color space. It is Generic RGB, whereas the color you create in code is Device RGB, which is sRGB.

Another way to see this is to do some logging. In the running app, the two colors are

<CGColor 0x60000296aa60> 
[<CGColorSpace 0x60000296ab20> 
    (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] 
( 0 0 1 1 )>

and

<CGColor 0x600002976940> 
[<CGColorSpace 0x60000296ab20> 
    (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] 
( 0.01675 0.198341 1 1 )>

As you can see, the second color has been converted to sRGB color space, which is not the same as the Generic RGB you started with, and thus we get a different color after the conversion.

and what would I change to make them look the same

If you set the storyboard color's colorspace to Device RGB and then set the sliders to give a simple blue, you'll end up with the same colors in the running app.

  • Related