重绘时保持集合视图单元格重叠
Keep Collection View Cells Overlapped When They Are Redrawn
我通过将集合视图布局的 minimumLineSpacing
属性 设置为负数来让我的单元格重叠。但是,当我滚动并重新绘制单元格时,它们现在以相反的方向重叠。我在下面放了照片。
当滚动集合视图并重绘单元格时,如何保持单元格重叠,如第一张图片所示?
import UIKit
class PopularView: UIView {
let cellID = "cellID"
// MARK: - Views
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = -55 // -------Allows Overlap-----
layout.itemSize = CGSize(width: SCREEN_WIDTH, height: 185)
layout.minimumInteritemSpacing = 17
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
view.backgroundColor = .white
return view
}()
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.dataSource = self
collectionView.register(PopularCell.self, forCellWithReuseIdentifier: cellID)
backgroundColor = .white
setupCollectionView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Setup
fileprivate func setupCollectionView() {
self.addSubview(collectionView)
collectionView.anchors(top: self.topAnchor, topPad: 0, bottom: self.bottomAnchor, bottomPad: 0, left: self.leftAnchor, leftPad: 0, right: self.rightAnchor, rightPad: 0, height: nil, width: nil)
collectionView.contentSize = CGSize(width: 700, height: 700)
}
}
extension PopularView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! PopularCell
cell.background.backgroundColor = .random
return cell
}
}
试试这个,可能对你有帮助:
1- 在您的单元格中,您可以在单元格中定义 innerView 并将框架设置为
let innerView:UIView = CGRect(x: 0,y: -overlapHeight,width: screenWidth, height:cell.height + overlapHeight)
cell?.contentView.addSubview(innerView)
2- 在初始化期间配置您的单元:
cell?.contentView.clipsToBounds = false
3-加载单元格时,设置z顺序:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.layer.zPosition = CGFloat(indexPath.row)
// configure your cell after here
}
您应该能够看到内容视图中的嵌套视图重叠。
我已经起草了示例代码,看起来并不完美,但可以帮助您入门:
private let reuseIdentifier = "Cell"
private let overlapHeight:CGFloat = 100
class CustomCollectionCell:UICollectionViewCell {
var innerView:UIView?
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 300))
self.backgroundColor = .darkGray
let innerView = UIView(frame: CGRect(x: 0,y: -overlapHeight,width: UIScreen.main.bounds.width,height: overlapHeight + self.contentView.frame.height))
self.innerView = innerView
innerView.layer.cornerRadius = 20
self.contentView.addSubview(innerView)
self.contentView.clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(color:UIColor?) {
innerView?.backgroundColor = color
}
}
import UIKit
private let reuseIdentifier = "Cell"
private let overlapHeight:CGFloat = 100
class CustomCollectionCell:UICollectionViewCell {
var innerView:UIView?
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .darkGray
let innerView = UIView(frame: CGRect(x: 0,y: -overlapHeight,width: UIScreen.main.bounds.width,height: overlapHeight + self.contentView.frame.height))
self.innerView = innerView
innerView.layer.cornerRadius = 20
self.contentView.addSubview(innerView)
self.contentView.clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(color:UIColor?) {
innerView?.backgroundColor = color
}
}
class CollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width, height: 190)
flowLayout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
flowLayout.scrollDirection = .vertical
flowLayout.minimumInteritemSpacing = 0.0
collectionView.collectionViewLayout = flowLayout
// Register cell classes
self.collectionView!.register(CustomCollectionCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 30
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.layer.zPosition = CGFloat(indexPath.row)
var color:UIColor?
switch indexPath.row % 4 {
case 0:
color = .purple
case 1:
color = .yellow
case 2:
color = .green
default:
color = .red
}
if let cell = cell as? CustomCollectionCell {
cell.configure(color: color)
}
return cell
}
}
结果:
我通过将集合视图布局的 minimumLineSpacing
属性 设置为负数来让我的单元格重叠。但是,当我滚动并重新绘制单元格时,它们现在以相反的方向重叠。我在下面放了照片。
当滚动集合视图并重绘单元格时,如何保持单元格重叠,如第一张图片所示?
import UIKit
class PopularView: UIView {
let cellID = "cellID"
// MARK: - Views
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = -55 // -------Allows Overlap-----
layout.itemSize = CGSize(width: SCREEN_WIDTH, height: 185)
layout.minimumInteritemSpacing = 17
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
view.backgroundColor = .white
return view
}()
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.dataSource = self
collectionView.register(PopularCell.self, forCellWithReuseIdentifier: cellID)
backgroundColor = .white
setupCollectionView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Setup
fileprivate func setupCollectionView() {
self.addSubview(collectionView)
collectionView.anchors(top: self.topAnchor, topPad: 0, bottom: self.bottomAnchor, bottomPad: 0, left: self.leftAnchor, leftPad: 0, right: self.rightAnchor, rightPad: 0, height: nil, width: nil)
collectionView.contentSize = CGSize(width: 700, height: 700)
}
}
extension PopularView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! PopularCell
cell.background.backgroundColor = .random
return cell
}
}
试试这个,可能对你有帮助:
1- 在您的单元格中,您可以在单元格中定义 innerView 并将框架设置为
let innerView:UIView = CGRect(x: 0,y: -overlapHeight,width: screenWidth, height:cell.height + overlapHeight)
cell?.contentView.addSubview(innerView)
2- 在初始化期间配置您的单元:
cell?.contentView.clipsToBounds = false
3-加载单元格时,设置z顺序:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.layer.zPosition = CGFloat(indexPath.row)
// configure your cell after here
}
您应该能够看到内容视图中的嵌套视图重叠。
我已经起草了示例代码,看起来并不完美,但可以帮助您入门:
private let reuseIdentifier = "Cell"
private let overlapHeight:CGFloat = 100
class CustomCollectionCell:UICollectionViewCell {
var innerView:UIView?
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 300))
self.backgroundColor = .darkGray
let innerView = UIView(frame: CGRect(x: 0,y: -overlapHeight,width: UIScreen.main.bounds.width,height: overlapHeight + self.contentView.frame.height))
self.innerView = innerView
innerView.layer.cornerRadius = 20
self.contentView.addSubview(innerView)
self.contentView.clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(color:UIColor?) {
innerView?.backgroundColor = color
}
}
import UIKit
private let reuseIdentifier = "Cell"
private let overlapHeight:CGFloat = 100
class CustomCollectionCell:UICollectionViewCell {
var innerView:UIView?
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .darkGray
let innerView = UIView(frame: CGRect(x: 0,y: -overlapHeight,width: UIScreen.main.bounds.width,height: overlapHeight + self.contentView.frame.height))
self.innerView = innerView
innerView.layer.cornerRadius = 20
self.contentView.addSubview(innerView)
self.contentView.clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(color:UIColor?) {
innerView?.backgroundColor = color
}
}
class CollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width, height: 190)
flowLayout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
flowLayout.scrollDirection = .vertical
flowLayout.minimumInteritemSpacing = 0.0
collectionView.collectionViewLayout = flowLayout
// Register cell classes
self.collectionView!.register(CustomCollectionCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 30
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.layer.zPosition = CGFloat(indexPath.row)
var color:UIColor?
switch indexPath.row % 4 {
case 0:
color = .purple
case 1:
color = .yellow
case 2:
color = .green
default:
color = .red
}
if let cell = cell as? CustomCollectionCell {
cell.configure(color: color)
}
return cell
}
}
结果: