Как рисовать вещи под текстом UILabel? - PullRequest
0 голосов
/ 03 января 2019

Я создал пользовательский подкласс 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) не нарисовал текст метки?

1 Ответ

0 голосов
/ 03 января 2019

Текст не виден, потому что "z-index" UIBezierPath s зависит от порядка, в котором они нарисованы.Другими словами, UIBezierPath s нарисованы друг на друге.

super.draw(rect) действительно рисует текст.Но когда вы поместите его в качестве первого утверждения, оно будет нарисовано first , поэтому все, что вы рисуете после этого, переходит поверх текста.Чтобы это исправить, вы должны вызвать super.draw(rect) last:

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!
}

В качестве альтернативы просто подкласс UIView, нарисуйте круг в draw(_:) и добавьте UILabel в качестве подпредставления этого.Преимущество такого подхода состоит в том, что он не зависит от реализации super.draw(_:), которая может измениться в будущем

...