ios - 如何在 UILabel 的文本下绘制东西?
问题描述
我创建了一个UILabel
中间有一个圆圈的自定义子类,标签的文本(这是一个数字)将位于圆圈的顶部。
我最初考虑使用 来执行此操作layer.cornerRadius
,但是当标签的宽度和高度不相等时,这不会创建一个圆圈。
我的意思是,对于宽度为 100、高度为 50 的标签,我仍然想要一个半径为 50 且中心位于 (50, 25) 的圆。
因此,我尝试用它UIBezierPath
来画圆。这是我尝试过的:
override func draw(_ rect: CGRect) {
super.draw(rect)
if bounds.height > bounds.width {
let y = (bounds.height - bounds.width) / 2
let path = UIBezierPath(ovalIn: CGRect(x: 0, y: y, width: bounds.width, height: bounds.width))
circleColor.setFill()
path.fill()
} else {
let x = (bounds.width - bounds.height) / 2
let path = UIBezierPath(ovalIn: CGRect(x: x, y: 0, width: bounds.height, height: bounds.height))
circleColor.setFill()
path.fill()
}
}
我放了super.draw(rect)
,因为我认为这会绘制标签的文本,但是当我运行应用程序时,我只看到圆圈而不是我的标签文本。
我很困惑,因为为什么没有super.draw(rect)
绘制标签的文字?
解决方案
看不到文本是因为UIBezierPath
s 的“z-index”取决于它们的绘制顺序。换句话说,UIBezierPath
s 被绘制在彼此之上。
super.draw(rect)
确实绘制了文本。但是当你把它作为第一个语句时,它会先被绘制,所以你之后绘制的所有内容都在文本之上。要解决此问题,您应该super.draw(rect)
最后调用:
override func draw(_ rect: CGRect) {
if bounds.height > bounds.width {
let y = (bounds.height - bounds.width) / 2
let path = UIBezierPath(ovalIn: CGRect(x: 0, y: y, width: bounds.width, height: bounds.width))
circleColor.setFill()
path.fill()
} else {
let x = (bounds.width - bounds.height) / 2
let path = UIBezierPath(ovalIn: CGRect(x: x, y: 0, width: bounds.height, height: bounds.height))
circleColor.setFill()
path.fill()
}
super.draw(rect) // <------- here!
}
或者,只需 subclass UIView
,在 中绘制圆圈draw(_:)
,然后添加 aUILabel
作为其子视图。如果这种方法的优点是它不依赖于 的实现super.draw(_:)
,未来可能会改变,
推荐阅读
- uwp - 使用 ReactiveUI 包的通用 Windows 应用程序无法在发布模式下构建
- javascript - 如何从多个子组件中获取表单值?
- reactjs - Javascript React:推送到 useState 中的数组
- multithreading - 如何在Queue中实现并发
- python - 需要从基于字符串的文本文件中查找动态变化的整数
- mongodb - 如何检查mongodb数据中是否存在字段
- .htaccess - 从根目录重定向到子目录后如何从子目录运行opencart
- docker - 使用 scp 在两个 docker 容器之间复制文件
- hyperledger-fabric - 在超级账本结构的 chaicode 中执行大量事务时超时到期
- c# - 如何使用 C# 使用 ALSA 在 Linux 中获取和设置音量?