Проблема заключается в использовании frame
в пределах draw(_:)
.Проблема в том, что frame
- это «размер и позиция представления в системе координат его суперпредставления » (выделение добавлено).То, как вы визуализируете эту форму в этом представлении, обычно не имеет никакого отношения к тому, где это представление расположено в его суперпредставлении.И если это представление не находится на 0, 0 его суперпредставления, вы можете испытать обрезку.
Но не используйте параметр rect
.«В первый раз, когда ваш вид отрисовывается, этот прямоугольник обычно представляет собой все видимые границы вашего вида.Однако во время последующих операций рисования прямоугольник может указывать только часть вашего вида ». Вы рискуете радикально изменить форму, если ОС решит, что нужно обновить только часть вашего CustomView
.
Использование bounds
, вместо этого, который находится в собственной системе координат представления.И использование minX
, minY
, maxX
и maxY
немного упрощает код.
@IBDesignable
class CustomView: UIView {
@IBInspectable var offset: CGFloat = 60 { didSet { setNeedsDisplay() } }
@IBInspectable var fillColor: UIColor = .red { didSet { setNeedsDisplay() } }
override func draw(_ rect: CGRect) {
let path = UIBezierPath()
path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
// Close the path. This will create the last line automatically.
path.close()
fillColor.setFill()
path.fill()
}
}
Asкроме того, я не устанавливаю маску.Если вы анимируете, может показаться неэффективным постоянно сбрасывать маску при каждом вызове draw
.Лично я бы просто установил цвет фона вида .clear
.Но это не относится к актуальному вопросу.