我尝试使用swift 1.2和xcode 6来实现图像中显示的结果。
基本上我想创建一个带有形状切割的视图,以便能够看到下面的视图来为我的应用程序制作教程。 我知道如何创建一个圆形的形状,但我不知道如何在视图中切出它。 我需要一个完整的例子来说明如何做到这一点。 提前致谢
答案 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
这是我在操场上制作的:
答案 2 :(得分:3)
最简单的方法是创建一个png图像,外部有一个部分透明的白色,中间有一个清晰的圆圈。然后将2个图像视图叠加在一起,将遮罩图像放在顶部,并将其设置为" opaque"标志为假。
您也可以通过创建CAShapeLayer并将其设置为使用半透明的白色来完成此操作,然后安装一个形状为正方形的形状,并将其切出形状。您可以在图像视图的图层上安装该形状图层。
最常用的方法是创建UIImageView的自定义子类,并让子类的init方法创建并安装形状图层。我昨天创建了一个要点,说明了创建UIImageView的自定义子类。这是链接:ImageViewWithGradient gist
这个要点创造了一个渐变层。改为使用它来创建一个形状图层是一件简单的事情,如果你修改了layoutSubviews方法,你可以调整视图和路径,如果调整了图像视图的大小。
好的,我采取了额外的步骤来创建一个创建裁剪图像视图的游乐场。你可以在ImageViewWithMask on github
找到它我的游乐场生成的图像如下所示:
答案 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
答案 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)
}
}