我想创建六边形按钮,如果它们以“蜂窝”方式显示,则不会重叠,并且只能选择正确的按钮。我在这里找到了掩蔽UIView 的子类,并将它用于我的 UIButton 类来进行掩蔽。它工作正常!
当我在视图中生成按钮时,按钮标题不可见。研究表明,我需要使用
super.layoutSubviews()
才能显示标题的文本。我的 print 方法显示标题已正确填充,并且与另一个对象类对应,但无论如何,标题都不会显示。预期的标题是“H”,打印日志显示标题存在于第一个按钮中:
Getting category: Category(date: 2021-07-11 10:29:45 +0000, categoryID: "C1", categoryTitle: "Home", shortTitle: "H", categoryColor: UIExtendedSRGBColorSpace 0.403922 0.643137 0.921569 1, isDefault: false)
setupProperties short title: H
Short button title: H
Button Title: Optional("H")
Getting category: Category(date: 2021-07-11 10:15:50 +0000, categoryID: "C2", categoryTitle: "", shortTitle: "", categoryColor: UIExtendedSRGBColorSpace 0.960784 0.960784 0.960784 1, isDefault: true)
setupProperties short title:
Short button title:
Button Title: nil
我什至尝试向 UIButton 子视图添加另一个标签,并以相同的方法将此标签放在前面,但它也不会显示。
是否有另一种方法可以强制自定义按钮显示标题文本,或者我是否必须创建 UILabel,标题与按钮位于相同位置并将其放置在按钮上方的图层中?这种方法不是首选...
是因为 UIButton 被多边形掩盖了吗?
六角按钮类:
class HexaButton: UIButton {
var path: UIBezierPath!
var category: Category!
init(cat: Category) {
super.init(frame: CGRect())
self.category = cat
self.setupProperties()
//self.layoutSubviews()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.setupProperties()
//self.layoutSubviews()
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
addTarget(self, action: #selector(touchDown), for: .touchDown)
self.setupProperties()
//self.layoutSubviews()
}
private func setupProperties(){
self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 10)
self.setTitleColor(UIColor.white, for: .normal)
self.setTitle(category.shortTitle, for: .normal)
print("setupProperties short title: \(category.shortTitle)")
}
override func layoutSubviews() {
super.layoutSubviews()
self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 10)
self.setTitleColor(UIColor.white, for: .normal)
self.setTitle(category.shortTitle, for: .normal)
}
override func draw(_ rect: CGRect) {
let lineWidth: CGFloat = 5
path = self.roundedPolygonPath(rect: self.bounds, lineWidth: lineWidth, sides: 6, cornerRadius: 10, rotationOffset: CGFloat(.pi / 2.0))
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = category.categoryColor.cgColor
shapeLayer.fillColor = category.categoryColor.cgColor
shapeLayer.path = path.cgPath
layer.addSublayer(shapeLayer)
}
@objc func touchDown(button: HexaButton, event: UIEvent) {
if let touch = event.touches(for: button)?.first {
let location = touch.location(in: button)
if path.contains(location) == false {
button.cancelTracking(with: nil)
}
}
}
public func roundedPolygonPath(rect: CGRect, lineWidth: CGFloat, sides: NSInteger, cornerRadius: CGFloat, rotationOffset: CGFloat = 0) -> UIBezierPath {
let path = UIBezierPath()
let theta: CGFloat = CGFloat(2.0 * .pi) / CGFloat(sides) // How much to turn at every corner
let width = min(rect.size.width, rect.size.height) // Width of the square
let center = CGPoint(x: rect.origin.x + width / 2.0, y: rect.origin.y + width / 2.0)
// Radius of the circle that encircles the polygon
// Notice that the radius is adjusted for the corners, that way the largest outer
// dimension of the resulting shape is always exactly the width - linewidth
let radius = (width - lineWidth + cornerRadius - (cos(theta) * cornerRadius)) / 2.0
// Start drawing at a point, which by default is at the right hand edge
// but can be offset
var angle = CGFloat(rotationOffset)
let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle))
path.move(to: CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta)))
for _ in 0..<sides {
angle += theta
let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle))
let tip = CGPoint(x: center.x + radius * cos(angle), y: center.y + radius * sin(angle))
let start = CGPoint(x: corner.x + cornerRadius * cos(angle - theta), y: corner.y + cornerRadius * sin(angle - theta))
let end = CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta))
path.addLine(to: start)
path.addQuadCurve(to: end, controlPoint: tip)
}
path.close()
// Move the path to the correct origins
let bounds = path.bounds
let transform = CGAffineTransform(translationX: -bounds.origin.x + rect.origin.x + lineWidth / 2.0, y: -bounds.origin.y + rect.origin.y + lineWidth / 2.0)
path.apply(transform)
return path
}
}
有人能指出我正确的方向吗?我错过了什么?谢谢