为每一行的 UICollectionViewCell 设置自定义 space
Set custom space for UICollectionViewCell for every rows
我使用 UiCollectionView 构建 ViewController,并创建了自定义视图以显示在每个单元格中。
这是我的控制器上用于显示、调整单元格大小的代码。
我需要在 UiCollectionView
中的每一行有 3 个单元格
class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{
@IBOutlet weak var collectionView: UICollectionView!
var listaCategorie = [CategoryModel]()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.listaCategorie.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let noOfCellsInRow = 3
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let totalSpace = flowLayout.sectionInset.left
+ flowLayout.sectionInset.right
+ 30
+ (flowLayout.minimumInteritemSpacing * CGFloat(noOfCellsInRow - 1))
let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(noOfCellsInRow))
return CGSize(width: 100, height: 130)
}
// UICollectionViewDelegateFlowLayout method
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let cellWidthPadding = collectionView.frame.size.width / 30
let cellHeightPadding = collectionView.frame.size.height / 4
return UIEdgeInsets(top: cellHeightPadding,left: cellWidthPadding, bottom: cellHeightPadding,right: cellWidthPadding)
}
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
var category = self.listaCategorie[indexPath.row];
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cella", for: indexPath) as! CustomCellViewsCategories
var puntoLuce = self.listaCategorie[indexPath.row];
cell.labelCategoryName.text = puntoLuce.description
//cell.image.image = UIImage(named: "light-bulb-2.png");
cell.backgroundColor = getUIColorFromRGBThreeIntegers(red: 63,green: 162,blue: 217);
cell.layer.cornerRadius = 6
cell.layer.masksToBounds = false;
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.layer.shadowOpacity = 0.5
//RECUPERO LA DIMENSIONE
let noOfCellsInRow = 4
//FINE RECUPERO DIMENSIONE
if(puntoLuce.imageUrl != ""){
let imageUrl:NSURL = NSURL(string: puntoLuce.imageUrl!)!
DispatchQueue.global(qos: .userInitiated).async {
let imageData:NSData = NSData(contentsOf: imageUrl as URL)!
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
cell.imageCategory.image = image
}
}
}
return cell
}
func getUIColorFromRGBThreeIntegers(red: Int, green: Int, blue: Int) -> UIColor {
return UIColor(red: CGFloat(Float(red) / 255.0),
green: CGFloat(Float(green) / 255.0),
blue: CGFloat(Float(blue) / 255.0),
alpha: CGFloat(1.0))
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.title = "ARRIVA ARRIVA"
//on click su label temp
let tap = UITapGestureRecognizer(target: self, action: #selector(HomeViewController.tapFunction))
getCategoryList()
collectionView.delegate = self // Unless you have already defined the delegate in IB
collectionView.dataSource = self // Unless you have already defined the dataSource in IB
self.collectionView.frame = self.collectionView.frame.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
}
@objc func tapFunction() {
// handle label tap here
print("click");
}
func getCategoryList(){
var params = [
"" : ""
]
let postUrl = APIRequest(endPoint: "category_list")
postUrl.sendRequest(parameters: params as! [String : String]) {
responseObject, error in
let user = CategoryModel(id: "0",
description: "Tutti",
imageUrl: "")
self.listaCategorie.append(user)
guard let responseObject = responseObject, error == nil else {
print(error ?? "Unknown error")
return
}
do{
let messageData = try JSONDecoder().decode(ResponseCategoryModel.self, from: responseObject)
var array = messageData.result
for categoryModel in array {
let user = CategoryModel(id: "",
description: categoryModel.categoryName,
imageUrl: categoryModel.image)
self.listaCategorie.append(user)
}
print(array.count);
DispatchQueue.main.async { // Correct
self.collectionView.reloadData()
}
}catch{
print("errore durante la decodifica dei dati")
}
}
}
但这是结果:
正如您从照片中看到的那样,3 个单元格中也有 space。有没有办法通过cells?
设置负space
编辑
我尝试在第一次响应时使用代码。这是结果
添加 UICollectionViewDelegateFlowLayout
委托并添加这些方法并根据您的要求更新您的值,例如:-
let edge : CGFloat = 10.0
let spacing : CGFloat = 10.0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let noOfColumn = 3
let collectionviewWidth = collectionView.frame.width
let bothEdge = CGFloat(edge + edge) // left + right
let excludingEdge = collectionviewWidth - bothEdge
let cellWidthExcludingSpaces = excludingEdge - ((noOfColumn-1) * spacing)
let finalCellWidth = cellWidthExcludingSpaces / noOfColumn
let height = finalCellWidth
return CGSize(width: finalCellWidth, height: height)
}
UICollectionViewCompositionalLayout
将为您提供一个自动调整为集合视图大小的布局。删除所有与流布局相关的代码,并在 viewDidLoad
:
中创建组合布局
// Cell will be the full height of the enclosing group
let cellHeight = NSCollectionLayoutDimension.fractionalHeight(1)
// Cell will be 1/3 width of the enclosing group
let cellWidth = NSCollectionLayoutDimension.fractionalWidth(0.333)
// The size of the cell
let size = NSCollectionLayoutSize(widthDimension: cellWidth, heightDimension: cellHeight)
// This item represents a single cell
let item = NSCollectionLayoutItem(layoutSize: size)
// The cell will be inset by these distances within the item
item.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
// The group will be a fixed height
let groupHeight = NSCollectionLayoutDimension.absolute(130)
// The group will occupy the full available width
let groupWidth = NSCollectionLayoutDimension.fractionalWidth(1)
// The group will repeat to hold as many of the cells as it can in a horizontal row before wrapping
let group = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: groupWidth, heightDimension: groupHeight), subitems: [item])
// The actual section, which consists of a single group
let section = NSCollectionLayoutSection(group: group)
// The insets of the group from the edge of the collection view
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
// Create and assign the layout
let layout = UICollectionViewCompositionalLayout(section: section)
collectionView.collectionViewLayout = layout
我试着把它分成几块,所以它很有意义,这些布局可能需要一些时间来让你的头脑清醒过来。
它为您提供以下纵向布局:
横向:
如果您想要固定的单元格大小,请使用 .absoluteWidth
作为单元格宽度,并向组中添加 interItemSpacing
的 .flexible
。
使用 UICollectionViewFlowLayout
你可以用比问题中更少的代码获得非常相似的结果。对于一个普通项目,我拥有的唯一与集合视图相关的代码是 viewDidLoad()
:
(collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset = .init(top: 10, left: 10, bottom: 10, right: 10)
那么这个单流布局委托方法:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var width = (collectionView.bounds.width - 20) / 3
width -= 10
return CGSize(width: width, height: 130)
}
这为您提供纵向或横向每行三列。
我使用 UiCollectionView 构建 ViewController,并创建了自定义视图以显示在每个单元格中。 这是我的控制器上用于显示、调整单元格大小的代码。 我需要在 UiCollectionView
中的每一行有 3 个单元格class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{
@IBOutlet weak var collectionView: UICollectionView!
var listaCategorie = [CategoryModel]()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.listaCategorie.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let noOfCellsInRow = 3
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let totalSpace = flowLayout.sectionInset.left
+ flowLayout.sectionInset.right
+ 30
+ (flowLayout.minimumInteritemSpacing * CGFloat(noOfCellsInRow - 1))
let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(noOfCellsInRow))
return CGSize(width: 100, height: 130)
}
// UICollectionViewDelegateFlowLayout method
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let cellWidthPadding = collectionView.frame.size.width / 30
let cellHeightPadding = collectionView.frame.size.height / 4
return UIEdgeInsets(top: cellHeightPadding,left: cellWidthPadding, bottom: cellHeightPadding,right: cellWidthPadding)
}
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
var category = self.listaCategorie[indexPath.row];
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cella", for: indexPath) as! CustomCellViewsCategories
var puntoLuce = self.listaCategorie[indexPath.row];
cell.labelCategoryName.text = puntoLuce.description
//cell.image.image = UIImage(named: "light-bulb-2.png");
cell.backgroundColor = getUIColorFromRGBThreeIntegers(red: 63,green: 162,blue: 217);
cell.layer.cornerRadius = 6
cell.layer.masksToBounds = false;
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.layer.shadowOpacity = 0.5
//RECUPERO LA DIMENSIONE
let noOfCellsInRow = 4
//FINE RECUPERO DIMENSIONE
if(puntoLuce.imageUrl != ""){
let imageUrl:NSURL = NSURL(string: puntoLuce.imageUrl!)!
DispatchQueue.global(qos: .userInitiated).async {
let imageData:NSData = NSData(contentsOf: imageUrl as URL)!
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
cell.imageCategory.image = image
}
}
}
return cell
}
func getUIColorFromRGBThreeIntegers(red: Int, green: Int, blue: Int) -> UIColor {
return UIColor(red: CGFloat(Float(red) / 255.0),
green: CGFloat(Float(green) / 255.0),
blue: CGFloat(Float(blue) / 255.0),
alpha: CGFloat(1.0))
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.title = "ARRIVA ARRIVA"
//on click su label temp
let tap = UITapGestureRecognizer(target: self, action: #selector(HomeViewController.tapFunction))
getCategoryList()
collectionView.delegate = self // Unless you have already defined the delegate in IB
collectionView.dataSource = self // Unless you have already defined the dataSource in IB
self.collectionView.frame = self.collectionView.frame.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
}
@objc func tapFunction() {
// handle label tap here
print("click");
}
func getCategoryList(){
var params = [
"" : ""
]
let postUrl = APIRequest(endPoint: "category_list")
postUrl.sendRequest(parameters: params as! [String : String]) {
responseObject, error in
let user = CategoryModel(id: "0",
description: "Tutti",
imageUrl: "")
self.listaCategorie.append(user)
guard let responseObject = responseObject, error == nil else {
print(error ?? "Unknown error")
return
}
do{
let messageData = try JSONDecoder().decode(ResponseCategoryModel.self, from: responseObject)
var array = messageData.result
for categoryModel in array {
let user = CategoryModel(id: "",
description: categoryModel.categoryName,
imageUrl: categoryModel.image)
self.listaCategorie.append(user)
}
print(array.count);
DispatchQueue.main.async { // Correct
self.collectionView.reloadData()
}
}catch{
print("errore durante la decodifica dei dati")
}
}
}
但这是结果:
正如您从照片中看到的那样,3 个单元格中也有 space。有没有办法通过cells?
设置负space编辑
我尝试在第一次响应时使用代码。这是结果
添加 UICollectionViewDelegateFlowLayout
委托并添加这些方法并根据您的要求更新您的值,例如:-
let edge : CGFloat = 10.0
let spacing : CGFloat = 10.0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let noOfColumn = 3
let collectionviewWidth = collectionView.frame.width
let bothEdge = CGFloat(edge + edge) // left + right
let excludingEdge = collectionviewWidth - bothEdge
let cellWidthExcludingSpaces = excludingEdge - ((noOfColumn-1) * spacing)
let finalCellWidth = cellWidthExcludingSpaces / noOfColumn
let height = finalCellWidth
return CGSize(width: finalCellWidth, height: height)
}
UICollectionViewCompositionalLayout
将为您提供一个自动调整为集合视图大小的布局。删除所有与流布局相关的代码,并在 viewDidLoad
:
// Cell will be the full height of the enclosing group
let cellHeight = NSCollectionLayoutDimension.fractionalHeight(1)
// Cell will be 1/3 width of the enclosing group
let cellWidth = NSCollectionLayoutDimension.fractionalWidth(0.333)
// The size of the cell
let size = NSCollectionLayoutSize(widthDimension: cellWidth, heightDimension: cellHeight)
// This item represents a single cell
let item = NSCollectionLayoutItem(layoutSize: size)
// The cell will be inset by these distances within the item
item.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
// The group will be a fixed height
let groupHeight = NSCollectionLayoutDimension.absolute(130)
// The group will occupy the full available width
let groupWidth = NSCollectionLayoutDimension.fractionalWidth(1)
// The group will repeat to hold as many of the cells as it can in a horizontal row before wrapping
let group = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: groupWidth, heightDimension: groupHeight), subitems: [item])
// The actual section, which consists of a single group
let section = NSCollectionLayoutSection(group: group)
// The insets of the group from the edge of the collection view
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
// Create and assign the layout
let layout = UICollectionViewCompositionalLayout(section: section)
collectionView.collectionViewLayout = layout
我试着把它分成几块,所以它很有意义,这些布局可能需要一些时间来让你的头脑清醒过来。
它为您提供以下纵向布局:
横向:
如果您想要固定的单元格大小,请使用 .absoluteWidth
作为单元格宽度,并向组中添加 interItemSpacing
的 .flexible
。
使用 UICollectionViewFlowLayout
你可以用比问题中更少的代码获得非常相似的结果。对于一个普通项目,我拥有的唯一与集合视图相关的代码是 viewDidLoad()
:
(collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset = .init(top: 10, left: 10, bottom: 10, right: 10)
那么这个单流布局委托方法:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var width = (collectionView.bounds.width - 20) / 3
width -= 10
return CGSize(width: width, height: 130)
}
这为您提供纵向或横向每行三列。