我如何在UICollectionView的一个部分设置单元格间距?我知道有一个属性minimumInteritemSpacing,我已经将它设置为5.0,但间距仍然没有出现5.0。我已经实现了flowout委托方法。
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 5.0;
}
我仍然没有得到想要的结果。我认为这是最小间距。有没有什么方法可以设置最大间距?
上面vojtech-vrbka的解决方案是正确的,但它会触发一个警告:
警告:UICollectionViewFlowLayout缓存的帧不匹配索引路径-缓存值:这可能是因为流布局子类layout是修改UICollectionViewFlowLayout返回的属性而没有复制它们
下面的代码应该修复它:
class CustomViewFlowLayout : UICollectionViewFlowLayout {
let cellSpacing:CGFloat = 4
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let original = super.layoutAttributesForElementsInRect(rect)
if let original = original {
let attributes = NSArray.init(array: original, copyItems: true) as! [UICollectionViewLayoutAttributes]
for (index, attribute) in attributes.enumerate() {
if index == 0 { continue }
let prevLayoutAttributes = attributes[index - 1]
let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
attribute.frame.origin.x = origin + cellSpacing
}
}
return attributes
}
return nil
}
}
我有问题与接受的答案,所以我更新了它,这是为我工作:
.h
@interface MaxSpacingCollectionViewFlowLayout : UICollectionViewFlowLayout
@property (nonatomic,assign) CGFloat maxCellSpacing;
@end
.m
@implementation MaxSpacingCollectionViewFlowLayout
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
if (attributes.count <= 0) return attributes;
CGFloat firstCellOriginX = ((UICollectionViewLayoutAttributes *)attributes[0]).frame.origin.x;
for(int i = 1; i < attributes.count; i++) {
UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
if (currentLayoutAttributes.frame.origin.x == firstCellOriginX) { // The first cell of a new row
continue;
}
UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
CGFloat prevOriginMaxX = CGRectGetMaxX(prevLayoutAttributes.frame);
if ((currentLayoutAttributes.frame.origin.x - prevOriginMaxX) > self.maxCellSpacing) {
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = prevOriginMaxX + self.maxCellSpacing;
currentLayoutAttributes.frame = frame;
}
}
return attributes;
}
@end
投票的答案(以及快速版本)有一个小问题:右边会有一个很大的空格。
这是因为流布局是定制的,以使单元格间距精确,具有浮动左行为。
我的解决方案是操纵部分插入,使部分是对齐中心,但间距是完全指定的。
在下面的截图中,项目/行间距正好是8pt,而左右插入部分将大于8pt(使其居中对齐):
这样的Swift代码:
private let minItemSpacing: CGFloat = 8
private let itemWidth: CGFloat = 100
private let headerHeight: CGFloat = 32
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Create our custom flow layout that evenly space out the items, and have them in the center
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
layout.minimumInteritemSpacing = minItemSpacing
layout.minimumLineSpacing = minItemSpacing
layout.headerReferenceSize = CGSize(width: 0, height: headerHeight)
// Find n, where n is the number of item that can fit into the collection view
var n: CGFloat = 1
let containerWidth = collectionView.bounds.width
while true {
let nextN = n + 1
let totalWidth = (nextN*itemWidth) + (nextN-1)*minItemSpacing
if totalWidth > containerWidth {
break
} else {
n = nextN
}
}
// Calculate the section inset for left and right.
// Setting this section inset will manipulate the items such that they will all be aligned horizontally center.
let inset = max(minItemSpacing, floor( (containerWidth - (n*itemWidth) - (n-1)*minItemSpacing) / 2 ) )
layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)
collectionView.collectionViewLayout = layout
}
回答Swift 3.0, Xcode 8
1.确保你设置了集合视图委托
class DashboardViewController: UIViewController {
@IBOutlet weak var dashboardCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
dashboardCollectionView.delegate = self
}
}
2.实现uicollectionviewdelegatflowlayout协议,而不是UICollectionViewDelegate。
extension DashboardViewController: UICollectionViewDelegateFlowLayout {
fileprivate var sectionInsets: UIEdgeInsets {
return .zero
}
fileprivate var itemsPerRow: CGFloat {
return 2
}
fileprivate var interitemSpace: CGFloat {
return 5.0
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let sectionPadding = sectionInsets.left * (itemsPerRow + 1)
let interitemPadding = max(0.0, itemsPerRow - 1) * interitemSpace
let availableWidth = collectionView.bounds.width - sectionPadding - interitemPadding
let widthPerItem = availableWidth / itemsPerRow
return CGSize(width: widthPerItem, height: widthPerItem)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return interitemSpace
}
}