根据设备尺寸圈出收集视图图像

时间:2018-12-20 10:25:18

标签: ios uicollectionview geometry

你好在我的水平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
}

我想在每台设备上画圈图像

1 个答案:

答案 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

这实际上是问题的核心。问题是您要根据框架高度设置拐角半径。但这假设您知道框架是什么。你不知道就像您自己说的那样,如果在视图上设置自动布局约束,则此方法将无效。为什么?由于事情发生的顺序:

  1. 首先,使用当前框架高度设置拐角半径。

  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)
    }
}

结果:

enter image description here

使用CircleImageView作为图像视图,您将获得正确的结果。我再说一遍:重要的是,无论随后如何调整CircleImageView本身的大小,它都将继续起作用。