Все в вашем коде неверно.
photoImageView!.layer.frame = photoImageView!.layer.frame.insetBy(dx: 0, dy: 0)
Эта строка не имеет смысла.Если вы вставляете кадр в ноль, вы не меняете его.Так что эта строка вообще ничего не делает.
photoImageView!.layer.masksToBounds = false
photoImageView!.clipsToBounds = true
* Уровень слоя masksToBounds
и вид clipsToBounds
фактически являются одним и тем же свойством.Таким образом, вы устанавливаете то же свойство на false
, а затем возвращаетесь к true
в следующей строке.Таким образом, первая из этих двух строк вообще ничего не делает.
photoImageView!.layer.cornerRadius = photoImageView!.frame.height/2
Это на самом деле суть дела.Проблема в том, что вы устанавливаете угловой радиус в соответствии с высотой рамки.Но это предполагает, что вы знаете, что такое кадр.Вы неКак вы сами сказали, это не сработает, если вы установите ограничения для автоматического размещения в своем представлении.Зачем?Из-за порядка, в котором происходят вещи:
Сначала вы используете текущую высоту кадра, чтобы установить радиус угла.
Затемограничения вступают в силу и меняют кадр.Так что теперь радиус угла, который вы установили ранее, больше не «соответствует» виду изображения.
Более того, установка радиуса угла - это паршивый способ обрезать вид на круг,Правильный способ - маска вид на реальный круг.
Итак, подведем итог: вы должны использовать подкласс UIImageView, который переопределяет свой собственный layoutSubviews
, чтобы установить свою собственную маску вкруг, который соответствует текущему размеру.Поскольку размер изменяется из-за ограничений, будет вызван layoutSubviews
, и ваш код изменит маску, чтобы соответствовать ей правильно.
(Белая круговая граница может быть еще одним слоем или подпредставлением, которое рисует круг.)
Вопрос возникает довольно часто, и я часто вижу, что cornerRadius
неправильно используется таким же образом, поэтому вот фактическая реализация:
class CircleImageView : UIImageView {
override func layoutSubviews() {
super.layoutSubviews()
self.layer.sublayers = nil
let radius = min(self.bounds.height, self.bounds.width)/2
let cen = CGPoint(x:self.bounds.width/2, y:self.bounds.height/2)
let r = UIGraphicsImageRenderer(size:self.bounds.size)
var im : UIImage?
var outline : UIImage?
r.image { ctx in
let con = ctx.cgContext
UIColor.black.setFill()
con.addArc(center: cen, radius: radius,
startAngle: 0, endAngle: .pi*2, clockwise: true)
let p = con.path
con.fillPath()
im = ctx.currentImage
con.clear(CGRect(origin:.zero, size:self.bounds.size))
con.addPath(p!)
UIColor.clear.setFill()
UIColor.white.setStroke() // border color, change as desired
con.setLineWidth(4) // border width, change as desired
con.strokePath()
outline = ctx.currentImage
}
// the circle mask
let iv = UIImageView(image:im)
iv.contentMode = .center
iv.frame = self.bounds
self.mask = iv
// the border
let iv2 = UIImageView(image:outline)
iv2.contentMode = .center
iv2.frame = self.bounds
self.addSubview(iv2)
}
}
Результат:
Используйте CircleImageView для просмотра изображений, и вы получите правильный результат.Я повторяю: важно то, что это будет продолжать работать независимо от того, как впоследствии изменяется размер самого CircleImageView.