[英]iOS UICollectionView background around cell
我的屏幕看起来像:
如您所见,有带有图像背景的 UICollectionView。 背景应该比原始图像更白。 但是集合视图的单元格必须是透明的并显示图像的原始部分。 有人知道怎么做吗?
基本思想将是:
下面是一个例子:
class SeeThruCollectionViewCell: UICollectionViewCell {
static let identifier = "seeThruCellIdentifier"
var theLabel: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .clear
v.textColor = .white
v.shadowColor = .black
v.shadowOffset = CGSize(width: 1, height: 1)
v.font = UIFont.boldSystemFont(ofSize: 17)
return v
}()
var overlayPath: UIBezierPath!
var transparentPath: UIBezierPath!
var fillLayer: CAShapeLayer!
var padding: CGRect!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() -> Void {
padding = CGRect.zero
// init and add the sublayer we'll use as a mask
fillLayer = CAShapeLayer()
layer.addSublayer(fillLayer)
// add a label
addSubview(theLabel)
// center the label
NSLayoutConstraint.activate([
theLabel.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0.0),
theLabel.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0.0),
])
}
override func layoutSubviews() {
super.layoutSubviews()
// overlayPath and transparentPath will combine to
// create a translucent mask with a transparent rect in the middle
overlayPath = UIBezierPath(rect: bounds)
var r = bounds
r.origin.x += padding.origin.x
r.origin.y += padding.origin.y
r.size.width -= r.origin.x + padding.size.width
r.size.height -= r.origin.y + padding.size.height
transparentPath = UIBezierPath(rect: r)
overlayPath.append(transparentPath)
overlayPath.usesEvenOddFillRule = true
fillLayer.path = overlayPath.cgPath
fillLayer.fillRule = kCAFillRuleEvenOdd
fillLayer.fillColor = UIColor(white: 1.0, alpha: 0.75).cgColor
}
}
class SeeThruViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var theCollectionView: UICollectionView = {
let v = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout())
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .clear
return v
}()
var theBackgroundImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
// translucent padding for cells
let pad = CGFloat(12)
let numItems = 10
let numSections = 1
override func viewDidLoad() {
super.viewDidLoad()
// add background image view
view.addSubview(theBackgroundImageView)
// add collection view view
view.addSubview(theCollectionView)
if let img = UIImage(named: "cvBKG") {
theBackgroundImageView.image = img
}
let guide = view.safeAreaLayoutGuide
// constrain background image view and collection view to same frames
NSLayoutConstraint.activate([
theBackgroundImageView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0.0),
theBackgroundImageView.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: 0.0),
theBackgroundImageView.leadingAnchor.constraint(equalTo: guide.leadingAnchor, constant: 0.0),
theBackgroundImageView.trailingAnchor.constraint(equalTo: guide.trailingAnchor, constant: 0.0),
theCollectionView.topAnchor.constraint(equalTo: theBackgroundImageView.topAnchor, constant: 0.0),
theCollectionView.bottomAnchor.constraint(equalTo: theBackgroundImageView.bottomAnchor, constant: 0.0),
theCollectionView.leadingAnchor.constraint(equalTo: theBackgroundImageView.leadingAnchor, constant: 0.0),
theCollectionView.trailingAnchor.constraint(equalTo: theBackgroundImageView.trailingAnchor, constant: 0.0),
])
// normal collection view tasks
theCollectionView.register(SeeThruCollectionViewCell.self, forCellWithReuseIdentifier: SeeThruCollectionViewCell.identifier)
theCollectionView.dataSource = self
theCollectionView.delegate = self
// we want ZERO spacing between the cells
if let flow = theCollectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flow.minimumLineSpacing = 0
flow.minimumInteritemSpacing = 0
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// set cell size to fill exactly two "columns"
if let flow = theCollectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flow.itemSize = CGSize(width: theCollectionView.frame.size.width / 2.0, height: theCollectionView.frame.size.width / 2.0)
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return numSections
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numItems
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SeeThruCollectionViewCell.identifier, for: indexPath) as! SeeThruCollectionViewCell
cell.theLabel.text = "Cell: \(indexPath.item)"
var padRect = CGRect(x: pad, y: pad, width: pad, height: pad)
if indexPath.item <= 1 {
// if it's the first row
// add paddingn on the top
padRect.origin.y = pad * 2
}
if indexPath.item % 2 == 0 {
// if it's the left "column"
// add padding on the left
padRect.origin.x = pad * 2
} else {
// if it's the right "column"
// add padding on the right
padRect.size.width = pad * 2
}
if indexPath.item / 2 >= (numItems / 2) - 1 {
// if it's the last row
// add paddingn on the bottom
padRect.size.height = pad * 2
}
cell.padding = padRect
return cell
}
}
将背景图像cvNKG.png
并将其添加到项目的 Assets 中,然后创建一个新的UIViewController
并将其类分配给SeeThruViewController
。 您应该能够按原样运行它。
结果:
注意:这是一个起点。 您(显然)需要根据需要添加标签,并且您需要处理诸如奇数项或行数未填满屏幕等情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.