尽管宽度相等,但集合视图网格的最后一行显示不同 - swift iOS
Collection view grid last row appears differently despite equal widths - swift iOS
我有一个固定的集合视图单元格 (UICollectionView) 网格,但底部行中的单元格在屏幕上总是显示为略小的宽度。 collectionViewLayout: UICollectionViewLayout sizeForItemAt 中使用的框架大小(或边界)和计算宽度对于所有行都是相同的。
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let settings = currentContents[indexPath.item]
let height = CGFloat(30)
//
var cellWidth = CGFloat()
let availableWidth = collectionView.bounds.size.width
print("available width", availableWidth)
let minimumWidth = floor(availableWidth / collectionContents.cellsPerRow5)
print("minmum width", minimumWidth)
cellWidth = minimumWidth * settings.portion - 1
print("cell width", cellWidth)
return CGSize(width: cellWidth, height: height)
}
我想让底行与其他行对齐,但无法想象在布局委托方法中返回值后改变宽度的情况(或如何修复) .
替换
即可
cellWidth = (minimumWidth * settings.portion) - 0.5
与
cellWidth = (minimumWidth * settings.portion)
指定 minimumInteritemSpacingForSectionAt
为 0.5 而不是 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.5
}
CVTVCell.swift
只需在将数据集放入 currentContents
后,在 awakeFromNib
方法中重新加载 UICollectionView
。请参考下面的示例代码。
override func awakeFromNib(){
super.awakeFromNib()
currentContents = collectionContents.allEndings[0]
self.cView.reloadData()
}
UIKit
不喜欢超过 2 位小数的值,将它们四舍五入或者它会为你做。
此处,UICollectionViewFlowLayout
舍入您的单元格大小并开始使用至少等于您指定的 minimumInteritemSpacing
的 "interitemspacing" 填充行。在最后一行,它恰好使用了 minimumInteritemSpacing
值,并没有填满整行。
使用更好的四舍五入值修复它,给人一种一切都完美对齐的错觉。
我通常使用这些扩展名:
extension CGFloat {
func xx_rounded(_ rule: FloatingPointRoundingRule = .down, toDecimals decimals: Int = 2) -> CGFloat {
let multiplier = CGFloat(pow(10.0, CGFloat(decimals)))
return (self * multiplier).rounded(.down) / multiplier
}
}
extension CGSize {
func xx_rounded(rule: FloatingPointRoundingRule = .down, toDecimals: Int = 2) -> CGSize {
return CGSize(
width: width.xx_rounded(rule, toDecimals: toDecimals),
height: height.xx_rounded(rule, toDecimals: toDecimals)
)
}
}
变化:
return CGSize(width: cellWidth, height: height)
到
return CGSize(width: cellWidth, height: height).xx_rounded()
我发现的最佳方法是在计算初始列宽后捕获剩余的 space(减 1 以避免向上舍入),然后将剩余的 space 用于其他列。
对于两列示例:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
if indexPath.item == 0 || indexPath.item == 1
{ rowHeight = 40 }
else { rowHeight = 30 }
var cellWidth = CGFloat()
let minimumWidth = floor(availableWidth / numberOfColumns)
var columnPortion = CGFloat()
let columnNumber = indexPath.item % Int(numberOfColumns)
switch columnNumber
{
case 0:
columnPortion = columnPortion1
cellWidth = minimumWidth * columnPortion - 10
remainder = availableWidth - cellWidth - 1
case 1:
columnPortion = columnPortionFinal
cellWidth = remainder
default:
break
}
return CGSize(width: cellWidth, height: rowHeight)
}
我有一个固定的集合视图单元格 (UICollectionView) 网格,但底部行中的单元格在屏幕上总是显示为略小的宽度。 collectionViewLayout: UICollectionViewLayout sizeForItemAt 中使用的框架大小(或边界)和计算宽度对于所有行都是相同的。
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let settings = currentContents[indexPath.item]
let height = CGFloat(30)
//
var cellWidth = CGFloat()
let availableWidth = collectionView.bounds.size.width
print("available width", availableWidth)
let minimumWidth = floor(availableWidth / collectionContents.cellsPerRow5)
print("minmum width", minimumWidth)
cellWidth = minimumWidth * settings.portion - 1
print("cell width", cellWidth)
return CGSize(width: cellWidth, height: height)
}
我想让底行与其他行对齐,但无法想象在布局委托方法中返回值后改变宽度的情况(或如何修复) .
替换
即可cellWidth = (minimumWidth * settings.portion) - 0.5
与
cellWidth = (minimumWidth * settings.portion)
指定 minimumInteritemSpacingForSectionAt
为 0.5 而不是 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.5
}
CVTVCell.swift
只需在将数据集放入 currentContents
后,在 awakeFromNib
方法中重新加载 UICollectionView
。请参考下面的示例代码。
override func awakeFromNib(){
super.awakeFromNib()
currentContents = collectionContents.allEndings[0]
self.cView.reloadData()
}
UIKit
不喜欢超过 2 位小数的值,将它们四舍五入或者它会为你做。
此处,UICollectionViewFlowLayout
舍入您的单元格大小并开始使用至少等于您指定的 minimumInteritemSpacing
的 "interitemspacing" 填充行。在最后一行,它恰好使用了 minimumInteritemSpacing
值,并没有填满整行。
使用更好的四舍五入值修复它,给人一种一切都完美对齐的错觉。
我通常使用这些扩展名:
extension CGFloat {
func xx_rounded(_ rule: FloatingPointRoundingRule = .down, toDecimals decimals: Int = 2) -> CGFloat {
let multiplier = CGFloat(pow(10.0, CGFloat(decimals)))
return (self * multiplier).rounded(.down) / multiplier
}
}
extension CGSize {
func xx_rounded(rule: FloatingPointRoundingRule = .down, toDecimals: Int = 2) -> CGSize {
return CGSize(
width: width.xx_rounded(rule, toDecimals: toDecimals),
height: height.xx_rounded(rule, toDecimals: toDecimals)
)
}
}
变化:
return CGSize(width: cellWidth, height: height)
到
return CGSize(width: cellWidth, height: height).xx_rounded()
我发现的最佳方法是在计算初始列宽后捕获剩余的 space(减 1 以避免向上舍入),然后将剩余的 space 用于其他列。
对于两列示例:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
if indexPath.item == 0 || indexPath.item == 1
{ rowHeight = 40 }
else { rowHeight = 30 }
var cellWidth = CGFloat()
let minimumWidth = floor(availableWidth / numberOfColumns)
var columnPortion = CGFloat()
let columnNumber = indexPath.item % Int(numberOfColumns)
switch columnNumber
{
case 0:
columnPortion = columnPortion1
cellWidth = minimumWidth * columnPortion - 10
remainder = availableWidth - cellWidth - 1
case 1:
columnPortion = columnPortionFinal
cellWidth = remainder
default:
break
}
return CGSize(width: cellWidth, height: rowHeight)
}