带有自定义边框的 UITextField 上的浮动 UILabel
Floating UILabel on UITextField with custom border
我基本上是在尝试创建一个 UITextField
,当用户输入内容时,它会在 UILabel
中几乎在顶部边框上显示占位符文本。
我已经设法让 UILabel
与动画和所有内容就位,除了 UITextField
的边框是 运行 通过 UILabel
当我给它(边框)自定义颜色和宽度。如果我离开标准的 RoundedRect
边框,而不给出 borderColor
或 borderWidth
,一切都会完美无缺。不过我需要颜色:/
(忽略红色背景 - 这样做是为了能见度)
自定义边框颜色穿过标签
这没有自定义边框(请参阅 - 没有边框穿过 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
来实现您的结果。
例如,为您的 UITextField
和 placeholderlabel
创建一个通用超级视图(不要将占位符标签添加为 UITextField 的子视图,例如将它们都添加到新的超级视图 UIView)。
谢谢大家的解答
在我求助于在这里发帖后的 2 个小时里,我一直坐在这个上面,我弄明白了。典型。
我专门尝试创建 UITextField
的子类,这样我就可以在任何地方重复使用它而不会遇到太多麻烦。这就是为什么我不想制作一个包含 UITextField
和 UILabel
作为子视图的 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
我基本上是在尝试创建一个 UITextField
,当用户输入内容时,它会在 UILabel
中几乎在顶部边框上显示占位符文本。
我已经设法让 UILabel
与动画和所有内容就位,除了 UITextField
的边框是 运行 通过 UILabel
当我给它(边框)自定义颜色和宽度。如果我离开标准的 RoundedRect
边框,而不给出 borderColor
或 borderWidth
,一切都会完美无缺。不过我需要颜色:/
(忽略红色背景 - 这样做是为了能见度)
自定义边框颜色穿过标签
这没有自定义边框(请参阅 - 没有边框穿过 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
来实现您的结果。
例如,为您的 UITextField
和 placeholderlabel
创建一个通用超级视图(不要将占位符标签添加为 UITextField 的子视图,例如将它们都添加到新的超级视图 UIView)。
谢谢大家的解答 在我求助于在这里发帖后的 2 个小时里,我一直坐在这个上面,我弄明白了。典型。
我专门尝试创建 UITextField
的子类,这样我就可以在任何地方重复使用它而不会遇到太多麻烦。这就是为什么我不想制作一个包含 UITextField
和 UILabel
作为子视图的 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