【发布时间】:2022-01-21 13:14:06
【问题描述】:
我创建了一个小项目 (Github link),演示如何在 UITextField 下添加一行以回答 this SO question。
OP 试图使用 CALayer 添加下划线,这就是我最初实现该解决方案的方式。对于那个版本,我创建了一个名为“UnderlinedTextField”的UITextField 的自定义子类。该自定义子类创建并维护一个具有背景颜色的 CALayer。
然后我注意到,在文本字段的底部简单地添加一个 1 点 UIView 会更容易。我更新了我的演示项目以说明这种方法。
这两种方法都在UITextField 下方添加了一条 1 点蓝线。基于视图的方法可以完成 Storyboard 中的所有操作,并且不需要任何代码。由于它使用 AutoLayout 约束将下划线视图固定到文本字段的底部,因此即使文本字段移动,约束也会将视图保持在正确的位置。
但是,我注意到基于图层的下划线和基于视图的下划线看起来不同,这是一个截图:
基于图层的下划线看起来更重。仔细看,基于图层的下划线的抗锯齿颜色比基于视图的下划线的抗锯齿颜色深。
为什么会这样,我会改变什么以使它们看起来一样?
(下面是UnderlinedTextField 类的代码,以防你不想去看 Github 仓库)
/// 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()
}
}
编辑:
我根据 Matt 的回答更改了我的项目(并推送了更改),以使 Storyboard 使用设备颜色配置文件。这使得下划线的颜色值非常接近,但仍不完全相同。
如果我使用“数字色度计”应用程序检查模拟器中的线条,顶部和底部的线条会略有不同。但是,如果我使用控件 S 将屏幕保存到模拟器中的磁盘(将其保存为全尺寸)并在 PS 中打开生成的图像,则线条显示为无锯齿的纯 sRGB 蓝色。我想将模拟器屏幕映射到 Mac 屏幕会导致 2 行的别名略有不同。
(您必须在 PS 或其他可让您查看像素颜色的应用程序中打开图片以检测两条线的差异。将情节提要的颜色配置文件更改为设备 RGB (sRGB) 后,我看不到差别太大了。)
【问题讨论】:
-
Xcode 和您介绍的资源(即 Adobe 的颜色空间定义与 Apple 的定义)中颜色空间的不同使用可能会让人头疼,这就是为什么我总是扩展
UIColor并定义我自己的颜色使用UIColor(hue:saturation:brightness:alpha:)以编程方式在 Storyboard 中也可用(使用 HSB 滑块创建自定义颜色),它们将始终保持同步。对于阅读本文的任何 Adobe 用户,sRGB 是您要用于 Xcode 资源的色彩空间。 -
@liquid 非常好的观点。我在回答中给出了不同的工作技术,但你的更好,因为它消除了整个问题。
-
@liquid,有时我发现 HSB 颜色空间对描述颜色很有用,而其他时候我想使用 RGB。之前在 PS 中取色时遇到过切换到 sRGB 的需求,所以我应该考虑检查 Storyboard 中的颜色配置文件。令人抓狂的是 IDE 的不同部分使用不同的颜色配置文件。