你好在我的水平collectionview中我想圈出图像,如果我设置静态的高度和宽度,它可以工作,但是如果我设置约束,它就不工作 iam使用此方法来圈出我的图片
public static func circularImageWhite(photoImageView: UIImageView?)
{
photoImageView!.layer.frame = photoImageView!.layer.frame.insetBy(dx: 0, dy: 0)
photoImageView!.layer.borderColor = UIColor.white.cgColor
photoImageView!.layer.cornerRadius = photoImageView!.frame.height/2
photoImageView!.layer.masksToBounds = false
photoImageView!.clipsToBounds = true
photoImageView!.layer.borderWidth = 1
photoImageView!.contentMode = UIViewContentMode.scaleAspectFill
}
我想在每台设备上画圈图像
答案 0 :(得分:0)
关于您的代码的所有信息都是错误的。
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本身的大小,它都将继续起作用。