我正在使用自定義 collectionview 做 Swift 應用程式。我想在其中顯示列行,我已經實作了。但是,我想在單元格內顯示網格線。
下面是我的代碼:
視圖控制器類
import UIKit
private let reuseIdentifier = "cell"
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var collectionView: UICollectionView!
var theData = [[String]]()
override func viewDidLoad() {
super.viewDidLoad()
theData = [
["1", "Name", "TV", "LCD", "LED", ""],
["2", "Market", "No", "Charge", "Discount", ""],
["3", "value", "2.00", "05.00", "49.30", "200", ""],
["4", "Coupons", "1", "1","1","1","Total Price: "]]
let layout = CustomLayout()
collectionView?.collectionViewLayout = layout
collectionView?.dataSource = self
collectionView?.delegate = self
layout.scrollDirection = .horizontal
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
collectionView?.contentInsetAdjustmentBehavior = .always
collectionView?.showsHorizontalScrollIndicator = false
}
// MARK: UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return theData[section].count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return theData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CustomCollectionViewCell
cell?.myLabel.text = theData[indexPath.section][indexPath.row]
return cell!
}
}
自定義collectionviewflowlayout類
import UIKit
class CustomLayout: UICollectionViewFlowLayout {
let itemWidth = 200
let itemHeight = 200
func collectionViewContentSize() -> CGSize {
let xSize = (collectionView?.numberOfItems(inSection: 0))! * (itemWidth 2) // the 2 is for spacing between cells.
let ySize = collectionView!.numberOfSections * (itemHeight 2)
return CGSize(width: xSize, height: ySize)
}
override func layoutAttributesForItem(at path: IndexPath?) -> UICollectionViewLayoutAttributes? {
var attributes: UICollectionViewLayoutAttributes? = nil
if let path = path {
attributes = UICollectionViewLayoutAttributes(forCellWith: path)
var xValue: Int
attributes?.size = CGSize(width: itemWidth, height: itemHeight)
xValue = itemWidth / 2 (path.row ) * (itemWidth 2)
let yValue = itemHeight (path.section ) * (itemHeight 2)
attributes?.center = CGPoint(x:CGFloat(xValue), y:CGFloat(yValue))
}
return attributes
}
func layoutAttributesForElements(in rect: CGRect) -> [AnyHashable]? {
let minRow = Int((rect.origin.x > 0) ? Int(rect.origin.x) / (itemWidth 2) : 0) // need to check because bounce gives negative values for x.
let maxRow = Int(Int(rect.size.width) / (itemWidth 2) minRow)
var attributes: [AnyHashable] = []
for i in 0..<(self.collectionView?.numberOfSections)! {
for j in (minRow..<maxRow) {
let indexPath = IndexPath(item: j, section: i)
attributes.append(layoutAttributesForItem(at: indexPath))
}
}
return attributes
}
}
此外,我想僅更改標題標題(1、2、3、4)的背景顏色。
有什么建議?

我想顯示如下截圖網格線

uj5u.com熱心網友回復:
如果您將有一個“固定網格” - 即 x 列 x y 行 - 您可以在 中計算單元格布局prepare(),將 保存cellAttributes在陣列中,然后將該陣列用于layoutAttributesForElements(in rect: CGRect):
class CustomLayout: UICollectionViewLayout {
private var computedContentSize: CGSize = .zero
private var cellAttributes = [IndexPath: UICollectionViewLayoutAttributes]()
let itemWidth = 100
let itemHeight = 60
let gridLineWidth = 1
override func prepare() {
guard let collectionView = collectionView else {
fatalError("not a collection view?")
}
// Clear out previous results
computedContentSize = .zero
cellAttributes = [IndexPath: UICollectionViewLayoutAttributes]()
let numItems = collectionView.numberOfItems(inSection: 0)
let numSections = collectionView.numberOfSections
let widthPlusGridLineWidth = itemWidth gridLineWidth
let heightPlusGridLineWidth = itemHeight gridLineWidth
for section in 0 ..< numSections {
for item in 0 ..< numItems {
let itemFrame = CGRect(x: item * widthPlusGridLineWidth gridLineWidth,
y: section * heightPlusGridLineWidth gridLineWidth,
width: itemWidth, height: itemHeight)
let indexPath = IndexPath(item: item, section: section)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = itemFrame
cellAttributes[indexPath] = attributes
}
}
computedContentSize = CGSize(width: numItems * widthPlusGridLineWidth gridLineWidth, height: numSections * heightPlusGridLineWidth gridLineWidth) // Store computed content size
}
override var collectionViewContentSize: CGSize {
return computedContentSize
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributeList = [UICollectionViewLayoutAttributes]()
for (_, attributes) in cellAttributes {
if attributes.frame.intersects(rect) {
attributeList.append(attributes)
}
}
return attributeList
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cellAttributes[indexPath]
}
}
然后您的控制器類變為:
class OutlinedGridViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
private let reuseIdentifier = "cell"
@IBOutlet var collectionView: UICollectionView!
var theData = [[String]]()
override func viewDidLoad() {
super.viewDidLoad()
// set view background to systemYellow so we can see the
// collection view frame
view.backgroundColor = .systemYellow
theData = [
["1", "Name", "TV", "LCD", "LED", "", ""],
["2", "Market", "No", "Charge", "Discount", "", ""],
["3", "value", "2.00", "05.00", "49.30", "200", ""],
["4", "Coupons", "1", "1","1","1","Total Price: "]]
let layout = CustomLayout()
collectionView.collectionViewLayout = layout
collectionView.dataSource = self
collectionView.delegate = self
collectionView.contentInsetAdjustmentBehavior = .always
collectionView.showsHorizontalScrollIndicator = false
collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
collectionView.backgroundColor = .black
}
// MARK: UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return theData.count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return theData[0].count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCollectionViewCell
let d = theData[indexPath.item]
cell.myLabel.text = d[indexPath.section]
// set background color for top row, else use white
cell.contentView.backgroundColor = indexPath.section == 0 ? .yellow : .white
return cell
}
}
and, using this custom cell (a single, centered label):
class CustomCollectionViewCell: UICollectionViewCell {
var myLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
myLabel.textColor = .black
myLabel.textAlignment = .center
myLabel.font = .systemFont(ofSize: 14.0)
myLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(myLabel)
let g = contentView
NSLayoutConstraint.activate([
myLabel.leadingAnchor.constraint(greaterThanOrEqualTo: g.leadingAnchor, constant: 4.0),
myLabel.trailingAnchor.constraint(lessThanOrEqualTo: g.trailingAnchor, constant: -4.0),
myLabel.centerXAnchor.constraint(equalTo: g.centerXAnchor),
myLabel.centerYAnchor.constraint(equalTo: g.centerYAnchor),
])
}
}
We get this (I made the collection view slightly smaller than needed, so we can see the horizontal and vertical scrolling):


You didn't explain what you want to do with the "Total Price" row... but if your intent is to have fewer columns on the last row, modifying this code will be a good exercise for you :)
uj5u.com熱心網友回復:
我無法真正完全理解您如何進行計算,因為它看起來.minimumInteritemSpacing并不.minimumLineSpacing像UICollectionViewFlowLayout水平滾動方向的正常作業那樣正常作業。
例如,檔案.minimumLineSpacing
對于水平滾動網格,此值表示連續列之間的最小間距。
但對你來說,它是行之間的間距。我認為子類 UICollectionViewLayout 而不是流布局可能會更好。
無論如何,作為解決方案,您可以執行以下操作:
首先,正如 DonMag 所說,讓您的收藏視圖與您的單元格顏色不同。
例如,將集合視圖設為黑色,將單元格設為白色。
由于您,.minimumLineSpacing似乎會影響行之間的間距,因此就像一條水平線,您可以將其設定為 1 或 2。
設定時您不會看到任何區別,因為這是同一部分minimumInteritemSpacing中單元格之間的間距,并且您部分中的專案也是垂直布局的。
因此,您需要在每列之間添加間距,sections因為您的每一列都是不同的部分,您可以使用sectionInset
因此,在將集合視圖的背景設定為橙色并將這些行添加到您的布局配置之后:
layout.minimumLineSpacing = 2
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 6)
盡管您需要在自定義布局類中修復一些計算以使其更好和更準確,但您獲得了一個足夠接近的解決方案。

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/443102.html
標籤:IOS 迅速 苹果手机 集合视图 uicollectionviewflowlayout
上一篇:org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class無法打開,因為它不存在
