У вас две проблемы.
Сначала вы устанавливаете shapeLayer.position = middleView.center
. center
вида - это геометрия суперпредставления. Другими словами, middleView.center
относится к view
, а не к middleView
. Но затем вы добавляете shapeLayer
в качестве подслоя middleView.layer
, что означает, что shapeLayer
нужен position
, который находится в геометрии middleView
, а не в геометрии view
. Вам нужно установить shapeLayer.position
в центр middleView.bounds
:
shapeLayer.position = CGPoint(x: middleView.bounds.midX, y: middleView.bounds.midY)
Во-вторых, вы не сказали, где вы все это делаете. Я думаю, вы делаете это в viewDidLoad
. Но это слишком рано. В viewDidLoad
представления, загруженные из раскадровки, по-прежнему имеют кадры, которые им были даны в раскадровке, и еще не были выложены для размера экрана текущего устройства. Поэтому не стоит смотреть на frame
(или bounds
или center
) в viewDidLoad
, если вы не сделаете что-то, чтобы убедиться, что все будет правильно выложено на этапе макета. Обычно вы делаете это, устанавливая autoresizingMask
или создавая ограничения. Пример: * * тысяча двадцать-шесть
let middleView = UIView(
frame: CGRect(x: 0.0,
y: view.frame.height/4,
width: view.frame.width,
height: view.frame.height/4))
middleView.backgroundColor = UIColor.blue
middleView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleTopMargin, .flexibleBottomMargin]
view.addSubview(middleView)
Однако shapeLayer
не принадлежит представлению, поэтому он не имеет autoresizingMask
и не может быть ограничен. Вы должны выложить это в коде. Вы можете сделать это, но лучше всего использовать представление для управления слоем формы. Таким образом, вы можете использовать autoresizingMask
или ограничения для управления макетом фигуры, и вы можете установить его в viewDidLoad
.
let circleView = CircleView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
circleView.center = CGPoint(x: middleView.bounds.midX, y: middleView.bounds.midY)
circleView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
circleView.shapeLayer.strokeColor = UIColor.purple.cgColor
circleView.shapeLayer.fillColor = nil
middleView.addSubview(circleView)
...
class CircleView: UIView {
override class var layerClass: AnyClass { return CAShapeLayer.self }
var shapeLayer: CAShapeLayer { return layer as! CAShapeLayer }
override func layoutSubviews() {
super.layoutSubviews()
shapeLayer.path = UIBezierPath(ovalIn: bounds).cgPath
}
}
Результат:
А после поворота в ландшафт: