Swift - 如何创建一个在其中裁剪的形状的视图

时间:2015-04-15 10:27:23

标签: swift uiview calayer

我尝试使用swift 1.2和xcode 6来实现图像中显示的结果。

基本上我想创建一个带有形状切割的视图,以便能够看到下面的视图来为我的应用程序制作教程。 我知道如何创建一个圆形的形状,但我不知道如何在视图中切出它。 我需要一个完整的例子来说明如何做到这一点。 提前致谢

Image

5 个答案:

答案 0 :(得分:14)

即使有答案,我也愿意分享我的方式:

// Let's say that you have an outlet to the image view called imageView
// Create the white view 
let whiteView = UIView(frame: imageView.bounds) 
let maskLayer = CAShapeLayer() //create the mask layer

// Set the radius to 1/3 of the screen width
let radius : CGFloat = imageView.bounds.width/3 

// Create a path with the rectangle in it.
let path = UIBezierPath(rect: imageView.bounds)
// Put a circle path in the middle
path.addArcWithCenter(imageView.center, radius: radius, startAngle: 0.0, endAngle: CGFloat(2*M_PI), clockwise: true)

// Give the mask layer the path you just draw
maskLayer.path = path.CGPath
// Fill rule set to exclude intersected paths
maskLayer.fillRule = kCAFillRuleEvenOdd

// By now the mask is a rectangle with a circle cut out of it. Set the mask to the view and clip.
whiteView.layer.mask = maskLayer
whiteView.clipsToBounds = true

whiteView.alpha = 0.8
whiteView.backgroundColor = UIColor.whiteColor()

//If you are in a VC add to the VC's view (over the image)
view.addSubview(whiteView)    
// Annnnnd you're done.

答案 1 :(得分:4)

以下是如何为UIView创建圆形蒙版的示例代码:

let sampleView = UIView(frame: UIScreen.mainScreen().bounds)
let maskLayer = CALayer()
maskLayer.frame = sampleView.bounds
let circleLayer = CAShapeLayer()
//assume the circle's radius is 100
circleLayer.frame = CGRectMake(sampleView.center.x - 100, sampleView.center.y - 100, 200, 200)
let circlePath = UIBezierPath(ovalInRect: CGRectMake(0, 0, 200, 200))
circleLayer.path = circlePath.CGPath
circleLayer.fillColor = UIColor.blackColor().CGColor
maskLayer.addSublayer(circleLayer)

sampleView.layer.mask = maskLayer

这是我在操场上制作的:

enter image description here

答案 2 :(得分:3)

最简单的方法是创建一个png图像,外部有一个部分透明的白色,中间有一个清晰的圆圈。然后将2个图像视图叠加在一起,将遮罩图像放在顶部,并将其设置为" opaque"标志为假。

您也可以通过创建CAShapeLayer并将其设置为使用半透明的白色来完成此操作,然后安装一个形状为正方形的形状,并将其切出形状。您可以在图像视图的图层上安装该形状图层。

最常用的方法是创建UIImageView的自定义子类,并让子类的init方法创建并安装形状图层。我昨天创建了一个要点,说明了创建UIImageView的自定义子类。这是链接:ImageViewWithGradient gist

这个要点创造了一个渐变层。改为使用它来创建一个形状图层是一件简单的事情,如果你修改了layoutSubviews方法,你可以调整视图和路径,如果调整了图像视图的大小。

编辑:

好的,我采取了额外的步骤来创建一个创建裁剪图像视图的游乐场。你可以在ImageViewWithMask on github

找到它

我的游乐场生成的图像如下所示:

Image with circular mask

答案 3 :(得分:2)

    //assume you create a UIImageView and content image before execute this code
  let sampleMask = UIView()
    sampleMask.frame = self.view.frame
    sampleMask.backgroundColor =  UIColor.black.withAlphaComponent(0.6)
    //assume you work in UIViewcontroller
    self.view.addSubview(sampleMask)
    let maskLayer = CALayer()
    maskLayer.frame = sampleMask.bounds
    let circleLayer = CAShapeLayer()
    //assume the circle's radius is 150
    circleLayer.frame = CGRect(x:0 , y:0,width: sampleMask.frame.size.width,height: sampleMask.frame.size.height)
    let finalPath = UIBezierPath(roundedRect: CGRect(x:0 , y:0,width: sampleMask.frame.size.width,height: sampleMask.frame.size.height), cornerRadius: 0)
    let circlePath = UIBezierPath(ovalIn: CGRect(x:sampleMask.center.x - 150, y:sampleMask.center.y - 150, width: 300, height: 300))
    finalPath.append(circlePath.reversing())
    circleLayer.path = finalPath.cgPath
    circleLayer.borderColor = UIColor.white.withAlphaComponent(1).cgColor
     circleLayer.borderWidth = 1
    maskLayer.addSublayer(circleLayer)

    sampleMask.layer.mask = maskLayer

enter image description here

答案 4 :(得分:0)

class MakeTransparentHoleOnOverlayView: UIView {

    @IBOutlet weak var transparentHoleView: UIView!

    // MARK: - Drawing

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        if self.transparentHoleView != nil {
            // Ensures to use the current background color to set the filling color
            self.backgroundColor?.setFill()
            UIRectFill(rect)

            let layer = CAShapeLayer()
            let path = CGMutablePath()

            // Make hole in view's overlay
            // NOTE: Here, instead of using the transparentHoleView UIView we could use a specific CFRect location instead...
            path.addRect(transparentHoleView.frame)
            path.addRect(bounds)

            layer.path = path
            layer.fillRule = kCAFillRuleEvenOdd
            self.layer.mask = layer
        }
    }

    override func layoutSubviews () {
        super.layoutSubviews()
    }

    // MARK: - Initialization

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
}