UICollectionViewCell间隔设置为0时仍有空隙的问题
解决UICollectionView间隔设置为0时仍有空隙的问题
明明把间距设置为0了为什么还有空隙呢 ?接着往下看有两个解决办法等着你。
例子:(我的代码)
#pragma mark -
//定义每个UICollectionView 的边距
- ( UIEdgeInsets )collectionView:( UICollectionView *)collectionView layout:( UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:( NSInteger )section {return UIEdgeInsetsMake(0, 0, 0, 0);
;
}
#pragma mark - X间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {return0;
}
#pragma mark - Y间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {return0;
}
- 首先应该了解一下
[[UIScreen mainScrenn] scale]
iPhone 4 之前的设备为1.0
iPhone 4 ~ iPhone 6s (除plus外) 的为2.0
iPhone 6 plus 和 iPhone 6s plus 的为3.0
对于iPhone 6 Plus之前的手机,pt和px的比例是1:2,而iPhone 6 Plus出来之后,这一比例达到了1:3,
还是不太明白的话可以谷歌一下,这里有篇扩展阅读: 「像素」「渲染像素」以及「物理像素」是什么东西?它们有什么联系?
造成缝隙的原因
【UICollectionViewCell间隔设置为0时仍有空隙的问题】iPhone6的屏幕像素(point,也叫逻辑像素)是375*667
,物理像素为750*1334
,等分4份的话每一个item的宽度是375/4=93.75
,这里是没有问题的,问题是屏幕能分的最小物理像素是1,而iPhone6的[[UIScreen mainScrenn] scale]
是2.0,也就是说1个屏幕像素(逻辑像素)对应有2个物理像素,即0.5个屏幕像素对应1个物理像素,而iPhone6四等分的宽度是93.75
,根据前面的分析有0.25
是不可再分的,这就是造成缝隙的原因。 同理iPhone6 Plus的[[UIScreen mainScrenn] scale]
是3.0,也就是说1个屏幕像素(逻辑像素)对应有3个物理像素,即0.333333个屏幕像素对应1个物理像素,四等分之后是414/4=103.5
,有0.16
是不可再分的,也会有缝隙。 ###解决办法 思路:只要itemSize的width的小数点后的值等于1 / [UIScreen mainScreen].scale
的值即可。
- 解决方法 一
- (CGFloat)fixSlitWith:(CGRect)rect colCount:(CGFloat)colCount space:(CGFloat)space {
CGFloat totalSpace = (colCount - 1) * space;
//总共留出的距离
CGFloat itemWidth = (rect.size.width - totalSpace) / colCount;
// 按照真实屏幕算出的cell宽度 (iPhone6 375*667)93.75
CGFloat fixValue = https://www.it610.com/article/1 / [UIScreen mainScreen].scale;
//(1px=0.5pt,6Plus为3px=1pt)
CGFloat realItemWidth = floor(itemWidth) + fixValue;
//取整加fixValuefloor:如果参数是小数,则求最大的整数但不大于本身.
if (realItemWidth < itemWidth) {// 有可能原cell宽度小数点后一位大于0.5
realItemWidth += fixValue;
}
CGFloat realWidth = colCount * realItemWidth + totalSpace;
//算出屏幕等分后满足1px=([UIScreen mainScreen].scale)pt实际的宽度,可能会超出屏幕,需要调整一下frame
CGFloat pointX = (realWidth - rect.size.width) / 2;
//偏移距离
rect.origin.x = -pointX;
//向左偏移
rect.size.width = realWidth;
_rect = rect;
return realItemWidth;
//每个cell的真实宽度
}
- 解决方法 二
重写layoutAttributesForElementsInRect方法即可
//
//GSCollectionViewFlowLayout.m
//SuperSearch
//
//Created by 巩小鹏 on 2018/4/17.
//Copyright ? 2018年 巩小鹏. All rights reserved.
//#import "GSCollectionViewFlowLayout.h"@interface GSCollectionViewFlowLayout()@end
@implementation GSCollectionViewFlowLayout#pragma mark - 初始化layout的结构和初始需要的参数
- (void)prepareLayout
{
[super prepareLayout];
}//#pragma mark - cell的左右间距- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {NSMutableArray * answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
/* 处理左右间距 */for(int i = 1;
i < [answer count];
++i) {UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
//注意:currentLayoutAttributes.indexPath.section 这里是单独处理某个section的空隙,如果不需要可把if判断删除即可
if (currentLayoutAttributes.indexPath.section == 0) {NSInteger maximumSpacing = 0;
NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = origin + maximumSpacing;
currentLayoutAttributes.frame = frame;
}
}}return answer;
}@end
推荐阅读
- 第6.2章(设置属性)
- 15、IDEA学习系列之其他设置(生成javadoc、缓存和索引的清理等)
- performSelectorOnMainThread:withObject:waitUntilDone:参数设置为NO或YES的区别
- spring|spring boot中设置异步请求默认使用的线程池
- Python绘制小红花
- day|day 28 设置路由表
- flutter设置沉浸式状态栏
- 谷歌/火狐/Safari浏览器设置手机模式浏览
- 自定义dialog在xml设置宽高失效的解决
- hive设置map和reduce数量