Бублик рисуется двумя концентрическими окружностями с even-odd заполнением. Если отверстие не должно нажиматься, ту же кольцевую область используют в hit testing.
Создать кнопку‑круг в виде бублика
Бублик рисуется двумя концентрическими окружностями с even-odd заполнением. Если отверстие не должно нажиматься, ту же кольцевую область используют в hit testing.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо реализовать кнопку, оформленную как бублик, при этом должно соблюдаться условие rect.width == rect.height, а радиус окружности известен.
Ответ
Бублик рисуется двумя концентрическими окружностями с even-odd заполнением. Если отверстие не должно нажиматься, ту же кольцевую область используют в hit testing.
Для UIKit внешний радиус равен половине стороны квадратных bounds; внутренний радиус задайте отдельно:
final class DonutButton: UIButton {
var innerRadius: CGFloat = 20 { didSet { setNeedsDisplay() } }
private var ring: UIBezierPath {
let outer = UIBezierPath(ovalIn: bounds)
let hole = CGRect(x: bounds.midX - innerRadius,
y: bounds.midY - innerRadius,
width: innerRadius * 2, height: innerRadius * 2)
outer.append(UIBezierPath(ovalIn: hole))
outer.usesEvenOddFillRule = true
return outer
}
override func draw(_ rect: CGRect) {
tintColor.setFill()
ring.fill()
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
ring.contains(point)
}
}
Задайте прозрачный фон, ограничения ширины/высоты 2R и 0 < innerRadius < R. Две окружности требуют внутреннего радиуса либо толщины кольца — одного внешнего радиуса недостаточно. Добавьте доступное название кнопки и визуальные состояния нажатия/disabled.