带有自定义边框的 UITextField 上的浮动 UILabel

Floating UILabel on UITextField with custom border

我基本上是在尝试创建一个 UITextField,当用户输入内容时,它会在 UILabel 中几乎在顶部边框上显示占位符文本。

我已经设法让 UILabel 与动画和所有内容就位,除了 UITextField 的边框是 运行 通过 UILabel 当我给它(边框)自定义颜色和宽度。如果我离开标准的 RoundedRect 边框,而不给出 borderColorborderWidth,一切都会完美无缺。不过我需要颜色:/

(忽略红色背景 - 这样做是为了能见度)

自定义边框颜色穿过标签

这没有自定义边框(请参阅 - 没有边框穿过 UILabel

是的 - 任何帮助将不胜感激。谢谢

来自 CALayer 中的 Apple 文档:

The border is drawn inset from the receiver’s bounds by borderWidth. It is composited above the receiver’s contents and sublayers and includes the effects of the cornerRadius property.

但是您可以通过将文本放入自己的 subview/sublayer 来实现您的结果。

例如,为您的 UITextFieldplaceholderlabel 创建一个通用超级视图(不要将占位符标签添加为 UITextField 的子视图,例如将它们都添加到新的超级视图 UIView)。

谢谢大家的解答 在我求助于在这里发帖后的 2 个小时里,我一直坐在这个上面,我弄明白了。典型。

我专门尝试创建 UITextField 的子类,这样我就可以在任何地方重复使用它而不会遇到太多麻烦。这就是为什么我不想制作一个包含 UITextFieldUILabel 作为子视图的 UIView - 然后我每次都必须这样做......不理想。

所以在深入研究 UITextField 的视图层次结构后,发现有一个子视图 _UITextFieldRoundedRectBackgroundViewNeue 总是第一个, 是一个持有 roundedRect 边界。通过 layer.border 添加自定义边框实际上将其添加到框架上 - 在整个视图层次结构的顶部。这就是为什么它会统治 UILabel.

的原因

所以我所做的就是将 layer.border 应用到 _UITextFieldRoundedRectBackgroundViewNeue,基本上强制边框始终位于底部,在所有内容的后面。

我建议任何执行此操作的人都检查一下 if subviews[0].classForCoder.description() == "_UITextFieldRoundedRectBackgroundViewNeue" 以确保它确实存在并确保您没有向您不期望的随机子视图添加边框。

现在,将 UILabel 添加到具有白色背景的实际 UITextField 对象,将产生浮动标签的效果。甜的。

这对我没有帮助。我没有找到“_UITextFieldRoundedRectBackgroundViewNeue”。但这对我有帮助:在 layoutsubviews() 中我创建了两个层,然后在 updateLayer() 中添加浮动占位符标签。 Floating Label 放在 whiteLabel

上方
public var floatingLabel = UILabel()
private var borderLayer = CAShapeLayer()
private var whiteLayer: CAShapeLayer = {
    let layer = CAShapeLayer()
    let path = UIBezierPath(rect: CGRect(x: 8, y: -2, width: 50, height: 4))
    layer.fillColor = UIColor.white.cgColor
    layer.path = path.cgPath
    return layer
}()

private func updateLayer() {
    layer.insertSublayer(borderLayer, at: 999)
    layer.insertSublayer(whiteLayer, above: borderLayer)
    let path = UIBezierPath(roundedRect: self.bounds, cornerRadius: 4)
    borderLayer.path = path.cgPath
    borderLayer.lineWidth = 1
    borderLayer.fillColor = UIColor.clear.cgColor
    addSubview(floatingLabel)
}

然后隐藏或显示 placeHolderLabel 只是隐藏 whiteLayer 然后你需要 - 添加 borderLayer.strokeColor