您应该使用 UICollectionView 的 mask 属性,将其设置为一个视图,其 alpha 通道指示您想要屏蔽 UICollectionView 的哪一部分。概括起来可能是这样的:
// If you don't have a custom subclass of UICollectionView... you can handle the resize in the
// UICollectionViewController or whatever view contoller is handling your view.
//
// If you do have a custom subclass of UICollectionView... you could do something similar
// in layoutSubviews.
class MyViewController : UICollectionViewController {
// recreate the mask after the view lays out it's subviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let maskImage = createMaskingImage(size: self.view.bounds.size) {
let maskView = UIView(frame: self.view.bounds)
maskView.layer.contents = maskImage
self.view.mask = maskView
}
}
}
// create a masking image for a view of the given size
func createMaskingImage(size: CGSize) -> UIImage? {
let drawingBounds = CGRect(origin: CGPoint.zero, size: size)
UIGraphicsBeginImageContext(size)
// We're going to jump down to the level of cgContext for scaling
// You might be able to do this from the level of UIGraphics, but I don't know how so...
// Implicitly unwrapped optional, but if we can't get a CGContext we're in trouble
let cgContext = UIGraphicsGetCurrentContext()!
let maskingPath = createMaskingPath()
let pathBounds = maskingPath.bounds;
cgContext.saveGState()
// Clearing the image may not strictly be necessary
cgContext.clear(drawingBounds)
// Scale the context so that when we draw the path it fits in the drawing bounds
// Could just use "size" here instead of drawingBounds.size, but I think this makes it a
// little more explicit that we're matching up two rects
cgContext.scaleBy(x: drawingBounds.size.width / pathBounds.size.width,
y: drawingBounds.size.height / pathBounds.size.height)
cgContext.setFillColor(UIColor.lightGray.cgColor)
cgContext.addPath(maskingPath.cgPath)
cgContext.fillPath(using: .evenOdd)
cgContext.restoreGState()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
func createMaskingPath() -> UIBezierPath {
let path = UIBezierPath()
path.move(to: CGPoint(x: 0.05, y: 0))
path.addCurve(to: CGPoint(x: 162.02, y: 3.8), controlPoint1: CGPoint(x: 0.05, y: 2.1), controlPoint2: CGPoint(x: 72.57, y: 3.8))
path.addCurve(to: CGPoint(x: 324, y: 0), controlPoint1: CGPoint(x: 251.48, y: 3.8), controlPoint2: CGPoint(x: 324, y: 2.1))
path.addLine(to: CGPoint(x: 324, y: 150.2))
path.addCurve(to: CGPoint(x: 162.02, y: 154), controlPoint1: CGPoint(x: 324, y: 152.3), controlPoint2: CGPoint(x: 251.48, y: 154))
path.addCurve(to: CGPoint(x: 0.05, y: 150.2), controlPoint1: CGPoint(x: 72.57, y: 154), controlPoint2: CGPoint(x: 0.05, y: 152.3))
path.addCurve(to: CGPoint(x: 0, y: 0.17), controlPoint1: CGPoint(x: 0.05, y: 148.1), controlPoint2: CGPoint(x: 0, y: 0.17))
return path
}